ฟังก์ชันระบบคลาวด์ช่วยให้คุณสามารถจัดการเหตุการณ์ใน
ฐานข้อมูลเรียลไทม์ของ Firebase โดยไม่ต้องอัปเดตโค้ดไคลเอ็นต์
Cloud Functions ช่วยให้คุณเรียกใช้การดำเนินการของ Realtime Database ด้วยการดูแลระบบเต็มรูปแบบ
สิทธิ์ และดูแลให้การเปลี่ยนแปลงที่คุณทำกับ Realtime Database แต่ละรายการได้รับการประมวลผล
แยกกัน คุณเปลี่ยนแปลงฐานข้อมูลเรียลไทม์ของ Firebase ได้ผ่าน
DataSnapshot
หรือผ่าน Admin SDK
ในวงจรทั่วไป ฟังก์ชันฐานข้อมูลเรียลไทม์ของ Firebase จะดำเนินการต่อไปนี้
- รอให้มีการเปลี่ยนแปลงตำแหน่งของ Realtime Database ที่เฉพาะเจาะจง
- ทริกเกอร์เมื่อเหตุการณ์เกิดขึ้นและทํางานของเหตุการณ์นั้น (โปรดดูฉันทำอะไรได้บ้าง) กับ Cloud Functions หรือไม่เพื่อดูตัวอย่าง กรณีการใช้งาน)
- รับออบเจ็กต์ข้อมูลที่มีสแนปชอตของข้อมูลที่จัดเก็บไว้ ในเอกสารที่ระบุ
ทริกเกอร์ฟังก์ชัน Realtime Database
สร้างฟังก์ชันใหม่สำหรับเหตุการณ์ใน Realtime Database
ด้วย functions.database
ถึง
ควบคุมเวลาที่ฟังก์ชันจะทริกเกอร์ ระบุตัวแฮนเดิลเหตุการณ์
ระบุเส้นทาง Realtime Database ที่จะรับข้อมูลเหตุการณ์
ตั้งค่าเครื่องจัดการเหตุการณ์
ฟังก์ชันต่างๆ ช่วยให้คุณจัดการเหตุการณ์ Realtime Database ได้ในระดับความจำ 2 ระดับ ได้แก่ คุณสามารถฟังเฉพาะ การสร้างสรรค์ อัปเดต เหตุการณ์การลบ หรือตรวจจับการเปลี่ยนแปลงใดๆ ก็ตามในเส้นทางได้ Cloud Functions รองรับตัวแฮนเดิลเหตุการณ์สำหรับฐานข้อมูลเรียลไทม์ต่อไปนี้
onWrite()
ซึ่งจะทริกเกอร์เมื่อมีการสร้าง อัปเดต หรือลบข้อมูลใน Realtime DatabaseonCreate()
ซึ่งจะทริกเกอร์เมื่อมีการสร้างข้อมูลใหม่ใน Realtime DatabaseonUpdate()
ซึ่งจะทำงานเมื่ออัปเดตข้อมูลใน Realtime DatabaseonDelete()
ซึ่งจะปรากฏเมื่อลบข้อมูลออกจาก Realtime Database
ระบุอินสแตนซ์และเส้นทาง
หากต้องการควบคุมเวลาและตําแหน่งที่ฟังก์ชันจะทริกเกอร์ ให้เรียกใช้ ref(path)
เพื่อระบุเส้นทาง และอาจระบุอินสแตนซ์ Realtime Database หรือไม่ก็ได้
ด้วย instance('INSTANCE_NAME')
หากไม่
ระบุอินสแตนซ์ ซึ่งจะทำให้ฟังก์ชันใช้งานได้กับอินสแตนซ์ฐานข้อมูลเรียลไทม์ตามค่าเริ่มต้น
ตัวอย่างโปรเจ็กต์ Firebase
- อินสแตนซ์ฐานข้อมูลเรียลไทม์เริ่มต้น:
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');
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);
});