Cloud Functions ช่วยให้คุณสามารถจัดการเหตุการณ์ใน
Firebase Realtime Database โดยไม่ต้องอัปเดตรหัสไคลเอ็นต์
Cloud Functions ให้คุณเรียกใช้การดำเนินการ Realtime Database ด้วยการดูแลระบบเต็มรูปแบบได้
และตรวจสอบว่าการเปลี่ยนแปลง Realtime Database แต่ละรายการได้รับการประมวลผล
แยกกัน คุณทำการเปลี่ยนแปลง Firebase Realtime Database รายการได้ผ่าน
DataSnapshot
หรือผ่าน Admin SDK
ในวงจรทั่วไป ฟังก์ชัน Firebase Realtime Database จะดำเนินการต่อไปนี้
- รอให้มีการเปลี่ยนแปลงในสถานที่หนึ่งๆ ของ Realtime Database
- ทริกเกอร์เมื่อเหตุการณ์เกิดขึ้นและทํางานของเหตุการณ์นั้น (โปรดดูฉันทำอะไรได้บ้าง) ด้วย Cloud Functions เพื่อดูตัวอย่าง กรณีการใช้งาน)
- รับออบเจ็กต์ข้อมูลที่มีสแนปชอตของข้อมูลที่จัดเก็บไว้ ในเอกสารที่ระบุ
ทริกเกอร์ฟังก์ชัน Realtime Database
สร้างฟังก์ชันใหม่ให้กับ Realtime Database เหตุการณ์
ด้วย functions.database
ถึง
ควบคุมเวลาที่ฟังก์ชันจะทริกเกอร์ ระบุตัวแฮนเดิลเหตุการณ์
ระบุเส้นทาง Realtime Database ที่จะตรวจจับเหตุการณ์
ตั้งค่าเครื่องจัดการเหตุการณ์
ฟังก์ชันช่วยให้คุณจัดการเหตุการณ์ Realtime Database ที่มีความเฉพาะเจาะจงได้ 2 ระดับ ได้แก่ คุณสามารถฟังเฉพาะ การสร้างสรรค์ อัปเดต เหตุการณ์การลบ หรือตรวจจับการเปลี่ยนแปลงใดๆ ก็ตามในเส้นทางได้ Cloud Functions รองรับตัวแฮนเดิลเหตุการณ์ต่อไปนี้สำหรับ Realtime Database
onWrite()
ซึ่งจะทริกเกอร์เมื่อมีการสร้าง อัปเดต หรือลบข้อมูลใน Realtime DatabaseonCreate()
ซึ่งจะทริกเกอร์เมื่อมีการสร้างข้อมูลใหม่ใน Realtime DatabaseonUpdate()
ซึ่งจะเรียกใช้งานเมื่ออัปเดตข้อมูลใน Realtime DatabaseonDelete()
ซึ่งจะทริกเกอร์เมื่อลบข้อมูลออกจาก Realtime Database
ระบุอินสแตนซ์และเส้นทาง
หากต้องการควบคุมเวลาและตําแหน่งที่ฟังก์ชันจะทริกเกอร์ ให้เรียกใช้ ref(path)
เพื่อระบุเส้นทาง และเลือกระบุอินสแตนซ์ Realtime Database (ไม่บังคับ)
กับ instance('INSTANCE_NAME')
หากไม่
ระบุอินสแตนซ์ ฟังก์ชันจะทำให้ใช้งานได้กับอินสแตนซ์ Realtime Database ที่เป็นค่าเริ่มต้นสำหรับ
ตัวอย่างโปรเจ็กต์ Firebase
- อินสแตนซ์ Realtime Database เริ่มต้น:
functions.database.ref('/foo/bar')
- อินสแตนซ์ชื่อ "my-app-db-2":
functions.database.instance('my-app-db-2').ref('/foo/bar')
วิธีการเหล่านี้จะกำหนดให้ฟังก์ชันจัดการการเขียนในบางเส้นทางภายใน
อินสแตนซ์ Realtime Database ข้อกำหนดเส้นทางตรงกับการเขียนทั้งหมดที่แตะเส้นทาง
รวมการเขียน
ที่เกิดขึ้นได้ทุกที่ด้านล่าง หากคุณกำหนดเส้นทางไว้
สำหรับฟังก์ชันในฐานะ /foo/bar
ฟังก์ชันนี้จะจับคู่กับเหตุการณ์ที่ทั้ง 2 ตำแหน่งนี้
/foo/bar
/foo/bar/baz/really/deep/path
ไม่ว่าในกรณีใดก็ตาม Firebase จะตีความว่าเหตุการณ์นั้นเกิดขึ้นที่ /foo/bar
และข้อมูลเหตุการณ์ประกอบด้วย
ข้อมูลเก่าและใหม่ไว้ที่ /foo/bar
หากข้อมูลเหตุการณ์อาจมีขนาดใหญ่
ให้พิจารณาใช้ฟังก์ชันหลายๆ อย่างในเส้นทางที่ลึกขึ้น
แทนที่จะใช้ฟังก์ชันเดียว
ที่อยู่ใกล้รากของฐานข้อมูล เพื่อประสิทธิภาพที่ดีที่สุด โปรดส่งคำขอเท่านั้น
ข้อมูลในระดับที่ลึกที่สุดเท่าที่เป็นไปได้
คุณระบุคอมโพเนนต์เส้นทางเป็นไวลด์การ์ดได้โดยล้อมรอบด้วยเส้นโค้ง
วงเล็บ ref('foo/{bar}')
ตรงกับรายการย่อยของ /foo
ค่าของ
คอมโพเนนต์เส้นทางไวลด์การ์ดจะพร้อมใช้งานภายใน
EventContext.params
ของฟังก์ชัน ในตัวอย่างนี้ ค่าจะแสดงเป็น
context.params.bar
เส้นทางที่มีไวลด์การ์ดสามารถจับคู่หลายเหตุการณ์จากการเขียนครั้งเดียว ส่วนแทรกของ
{
"foo": {
"hello": "world",
"firebase": "functions"
}
}
ตรงกับเส้นทาง "/foo/{bar}"
2 ครั้ง: 1 ครั้งด้วย "hello": "world"
และอีกครั้งกับ "firebase": "functions"
จัดการข้อมูลเหตุการณ์
เมื่อจัดการเหตุการณ์ Realtime Database ออบเจ็กต์ข้อมูลที่แสดงผลคือ
DataSnapshot
สำหรับกิจกรรม onWrite
หรือ onUpdate
พารามิเตอร์
พารามิเตอร์แรกคือออบเจ็กต์ Change
ที่มีสแนปชอต 2 รายการ
ที่แสดงถึงสถานะข้อมูลก่อน
และหลังเหตุการณ์ทริกเกอร์ สำหรับ onCreate
และ onDelete
กิจกรรม
ออบเจ็กต์ข้อมูลที่แสดงผลเป็นภาพรวมของข้อมูลที่สร้างหรือลบ
ในตัวอย่างนี้ ฟังก์ชันจะเรียกสแนปชอตสำหรับ เส้นทางที่ระบุจะแปลงสตริงในตำแหน่งนั้นเป็นตัวพิมพ์ใหญ่ และเขียนสตริงที่แก้ไขแล้วลงในฐานข้อมูล
// Listens for new messages added to /messages/:pushId/original and creates an // uppercase version of the message to /messages/:pushId/uppercase exports.makeUppercase = functions.database.ref('/messages/{pushId}/original') .onCreate((snapshot, context) => { // Grab the current value of what was written to the Realtime Database. const original = snapshot.val(); functions.logger.log('Uppercasing', context.params.pushId, original); const uppercase = original.toUpperCase(); // You must return a Promise when performing asynchronous tasks inside a Functions such as // writing to the Firebase Realtime Database. // Setting an "uppercase" sibling in the Realtime Database returns a Promise. return snapshot.ref.parent.child('uppercase').set(uppercase); });
การเข้าถึงข้อมูลการตรวจสอบสิทธิ์ผู้ใช้
จาก EventContext.auth
และ EventContext.authType
คุณสามารถเข้าถึง
ข้อมูลผู้ใช้ รวมถึงสิทธิ์ สำหรับผู้ใช้ที่ทริกเกอร์
ฟังก์ชัน ซึ่งจะเป็นประโยชน์ในการบังคับใช้กฎความปลอดภัย
ทำให้ฟังก์ชันของคุณทำงานแตกต่างกันไปตาม
ระดับของสิทธิ์:
const functions = require('firebase-functions/v1');
const admin = require('firebase-admin');
exports.simpleDbFunction = functions.database.ref('/path')
.onCreate((snap, context) => {
if (context.authType === 'ADMIN') {
// do something
} else if (context.authType === 'USER') {
console.log(snap.val(), 'written by', context.auth.uid);
}
});
นอกจากนี้ คุณยังใช้ประโยชน์จากข้อมูลการตรวจสอบสิทธิ์ของผู้ใช้เพื่อ "แอบอ้าง" ได้อีกด้วย ผู้ใช้ และดำเนินการเขียนในนามของผู้ใช้ อย่าลืมลบ อินสแตนซ์ของแอปดังที่แสดงด้านล่างเพื่อป้องกันปัญหาการเกิดขึ้นพร้อมกัน
exports.impersonateMakeUpperCase = functions.database.ref('/messages/{pushId}/original')
.onCreate((snap, context) => {
const appOptions = JSON.parse(process.env.FIREBASE_CONFIG);
appOptions.databaseAuthVariableOverride = context.auth;
const app = admin.initializeApp(appOptions, 'app');
const uppercase = snap.val().toUpperCase();
const ref = snap.ref.parent.child('uppercase');
const deleteApp = () => app.delete().catch(() => null);
return app.database().ref(ref).set(uppercase).then(res => {
// Deleting the app is necessary for preventing concurrency leaks
return deleteApp().then(() => res);
}).catch(err => {
return deleteApp().then(() => Promise.reject(err));
});
});
การอ่านค่าก่อนหน้า
ออบเจ็กต์ Change
มี
before
พร็อพเพอร์ตี้ที่ช่วยให้ตรวจสอบข้อมูลที่บันทึกไว้ใน Realtime Database ก่อน
กิจกรรม พร็อพเพอร์ตี้ before
แสดง DataSnapshot
ซึ่งทั้งหมด
(เช่น
val()
และ
exists()
)
อ้างอิงถึงค่าก่อนหน้า คุณสามารถอ่านค่าใหม่อีกครั้งโดยใช้
DataSnapshot
ต้นฉบับหรือการอ่าน
after
พร็อพเพอร์ตี้นี้ใน Change
ใดก็ได้เป็น DataSnapshot
อื่นที่แสดงถึง
สถานะของข้อมูลหลังที่เหตุการณ์เกิดขึ้น
ตัวอย่างเช่น สามารถใช้พร็อพเพอร์ตี้ before
เพื่อตรวจสอบว่ามีเพียงฟังก์ชันนี้
ข้อความตัวพิมพ์ใหญ่เมื่อสร้างครั้งแรก:
exports.makeUppercase = functions.database.ref('/messages/{pushId}/original')
.onWrite((change, context) => {
// Only edit data when it is first created.
if (change.before.exists()) {
return null;
}
// Exit when the data is deleted.
if (!change.after.exists()) {
return null;
}
// Grab the current value of what was written to the Realtime Database.
const original = change.after.val();
console.log('Uppercasing', context.params.pushId, original);
const uppercase = original.toUpperCase();
// You must return a Promise when performing asynchronous tasks inside a Functions such as
// writing to the Firebase Realtime Database.
// Setting an "uppercase" sibling in the Realtime Database returns a Promise.
return change.after.ref.parent.child('uppercase').set(uppercase);
});