คุณอาจพบว่าการตรวจหาผู้ใช้หรืออุปกรณ์ที่ออนไลน์อยู่มีประโยชน์ ทั้งนี้ขึ้นอยู่กับประเภทแอปที่คุณสร้าง ซึ่งก็คือการตรวจหา "การปรากฏ"
เช่น หากกำลังสร้างแอปอย่างโซเชียลเน็ตเวิร์กหรือกำลังติดตั้งใช้งานอุปกรณ์ IoT จำนวนมาก คุณอาจใช้ข้อมูลนี้เพื่อแสดงรายการเพื่อนที่ออนไลน์อยู่และพร้อมแชท หรือจัดเรียงอุปกรณ์ IoT ตาม "เวลาที่ออนไลน์ครั้งล่าสุด"
Cloud Firestore ไม่ได้รองรับการตรวจหาบุคคลโดยค่าเริ่มต้น แต่คุณสามารถ ใช้ประโยชน์จากผลิตภัณฑ์อื่นๆ ของ Firebase เพื่อสร้างระบบการตรวจหาบุคคลในบ้าน
โซลูชัน: Cloud Functions ที่มี Realtime Database
หากต้องการเชื่อมต่อ Cloud Firestore กับโฆษณาเนทีฟของฐานข้อมูลเรียลไทม์ของ Firebase การตรวจหาบุคคลในบ้าน ให้ใช้ฟังก์ชันระบบคลาวด์
ใช้ฐานข้อมูลเรียลไทม์เพื่อรายงานสถานะการเชื่อมต่อ จากนั้นใช้ Cloud Functions เพื่อมิเรอร์ข้อมูลดังกล่าวไปยัง Cloud Firestore
การใช้สถานะใน Realtime Database
ก่อนอื่น ให้พิจารณาวิธีการทำงานของระบบการปรากฏตัวแบบดั้งเดิมใน Realtime Database
เว็บ
// Fetch the current user's ID from Firebase Authentication. var uid = firebase.auth().currentUser.uid; // Create a reference to this user's specific status node. // This is where we will store data about being online/offline. var userStatusDatabaseRef = firebase.database().ref('/status/' + uid); // We'll create two constants which we will write to // the Realtime database when this device is offline // or online. var isOfflineForDatabase = { state: 'offline', last_changed: firebase.database.ServerValue.TIMESTAMP, }; var isOnlineForDatabase = { state: 'online', last_changed: firebase.database.ServerValue.TIMESTAMP, }; // Create a reference to the special '.info/connected' path in // Realtime Database. This path returns `true` when connected // and `false` when disconnected. firebase.database().ref('.info/connected').on('value', function(snapshot) { // If we're not currently connected, don't do anything. if (snapshot.val() == false) { return; }; // If we are currently connected, then use the 'onDisconnect()' // method to add a set which will only trigger once this // client has disconnected by closing the app, // losing internet, or any other means. userStatusDatabaseRef.onDisconnect().set(isOfflineForDatabase).then(function() { // The promise returned from .onDisconnect().set() will // resolve as soon as the server acknowledges the onDisconnect() // request, NOT once we've actually disconnected: // https://firebase.google.com/docs/reference/js/firebase.database.OnDisconnect // We can now safely set ourselves as 'online' knowing that the // server will mark us as offline once we lose connection. userStatusDatabaseRef.set(isOnlineForDatabase); }); });
ตัวอย่างนี้เป็นระบบการแสดงข้อมูลของ Realtime Database ที่สมบูรณ์ จัดการ การยกเลิกการเชื่อมต่อ การขัดข้อง และอื่นๆ หลายครั้ง
กำลังเชื่อมต่อกับ Cloud Firestore
เมื่อต้องการนำโซลูชันที่คล้ายกันไปใช้ใน Cloud Firestore ให้ใช้สิ่งเดียวกัน โค้ด Realtime Database แล้วใช้ฟังก์ชัน Cloud Functions เพื่อเก็บ Realtime Database และ Cloud Firestore ซิงค์อยู่
หากยังไม่ได้เพิ่ม ให้เพิ่ม Realtime Database ลงในโปรเจ็กต์และใส่โซลูชันการแสดงข้อมูลข้างต้น
ถัดไปคุณจะต้องซิงค์สถานะการตรวจหาบุคคลกับ Cloud Firestore ผ่าน วิธีการต่อไปนี้
- ในเครื่อง ไปยังแคช Cloud Firestore ของอุปกรณ์ที่ออฟไลน์ เพื่อให้แอป รู้ว่าออฟไลน์อยู่
- ทั่วโลกโดยใช้ฟังก์ชัน Cloud เพื่อให้อุปกรณ์อื่นๆ ทั้งหมดที่เข้าถึง Cloud Firestore ทราบว่าอุปกรณ์เครื่องนี้ออฟไลน์อยู่
อัปเดตแคชในเครื่องของ Cloud Firestore
มาดูการเปลี่ยนแปลงที่จําเป็นในการแก้ไขปัญหาแรกกัน นั่นคือ การอัปเดตแคชในเครื่องของCloud Firestore
เว็บ
// ... var userStatusFirestoreRef = firebase.firestore().doc('/status/' + uid); // Firestore uses a different server timestamp value, so we'll // create two more constants for Firestore state. var isOfflineForFirestore = { state: 'offline', last_changed: firebase.firestore.FieldValue.serverTimestamp(), }; var isOnlineForFirestore = { state: 'online', last_changed: firebase.firestore.FieldValue.serverTimestamp(), }; firebase.database().ref('.info/connected').on('value', function(snapshot) { if (snapshot.val() == false) { // Instead of simply returning, we'll also set Firestore's state // to 'offline'. This ensures that our Firestore cache is aware // of the switch to 'offline.' userStatusFirestoreRef.set(isOfflineForFirestore); return; }; userStatusDatabaseRef.onDisconnect().set(isOfflineForDatabase).then(function() { userStatusDatabaseRef.set(isOnlineForDatabase); // We'll also add Firestore set here for when we come online. userStatusFirestoreRef.set(isOnlineForFirestore); }); });
ปัจจุบันการเปลี่ยนแปลงเหล่านี้ทำให้เรามั่นใจว่าสถานะ Cloud Firestore ในท้องถิ่นจะปรากฏอยู่เสมอ
แสดงสถานะออนไลน์/ออฟไลน์ของอุปกรณ์ ซึ่งหมายความว่าคุณสามารถฟัง
/status/{uid}
เอกสารและใช้ข้อมูลเพื่อเปลี่ยน UI เพื่อแสดงการเชื่อมต่อ
สถานะ
เว็บ
userStatusFirestoreRef.onSnapshot(function(doc) { var isOnline = doc.data().state == 'online'; // ... use isOnline });
กำลังอัปเดตCloud Firestoreทั่วโลก
แม้ว่าแอปพลิเคชันของเราจะรายงานสถานะการออนไลน์ให้ตัวเองทราบอย่างถูกต้อง แต่สถานะนี้
จะยังไม่ถูกต้องในแอปอื่นๆ ของ Cloud Firestore เนื่องจาก "ออฟไลน์"
การเขียนสถานะเป็นแบบภายในเท่านั้นและจะไม่ถูกซิงค์เมื่อกลับมาเชื่อมต่ออีกครั้ง เราจะใช้ Cloud Functions ที่คอยตรวจสอบเส้นทาง status/{uid}
ในฐานข้อมูลเรียลไทม์เพื่อรับมือกับปัญหานี้ เมื่อค่า Realtime Database เปลี่ยนแปลง ค่าจะซิงค์กับ Cloud Firestore
เพื่อให้ผู้ใช้ทุกคน อย่างถูกต้อง
Node.js
firebase.firestore().collection('status') .where('state', '==', 'online') .onSnapshot(function(snapshot) { snapshot.docChanges().forEach(function(change) { if (change.type === 'added') { var msg = 'User ' + change.doc.id + ' is online.'; console.log(msg); // ... } if (change.type === 'removed') { var msg = 'User ' + change.doc.id + ' is offline.'; console.log(msg); // ... } }); });
เมื่อทำให้ฟังก์ชันนี้ใช้งานได้แล้ว คุณจะใช้ระบบการตรวจหาบุคคลในบ้านได้อย่างสมบูรณ์
ด้วย Cloud Firestore ด้านล่างนี้คือตัวอย่างการตรวจสอบผู้ใช้ที่ออนไลน์หรือออฟไลน์โดยใช้การค้นหา where()
เว็บ
firebase.firestore().collection('status') .where('state', '==', 'online') .onSnapshot(function(snapshot) { snapshot.docChanges().forEach(function(change) { if (change.type === 'added') { var msg = 'User ' + change.doc.id + ' is online.'; console.log(msg); // ... } if (change.type === 'removed') { var msg = 'User ' + change.doc.id + ' is offline.'; console.log(msg); // ... } }); });
ข้อจำกัด
การใช้ Realtime Database เพื่อเพิ่มการมีตัวตนในแอป Cloud Firestore นั้น สามารถปรับขนาดได้และมีประสิทธิภาพ แต่มีข้อจำกัดบางประการดังนี้
- การดีเบานซ์ - เมื่อฟังการเปลี่ยนแปลงแบบเรียลไทม์ใน Cloud Firestore โซลูชันนี้น่าจะทำให้เกิด การเปลี่ยนแปลง หากการเปลี่ยนแปลงเหล่านี้ทริกเกอร์เหตุการณ์มากกว่าที่คุณต้องการ ให้กรองเหตุการณ์ Cloud Firestore ด้วยตนเอง
- การเชื่อมต่อ - การติดตั้งใช้งานนี้วัดการเชื่อมต่อกับแบบเรียลไทม์ ฐานข้อมูล ไม่ใช่ Cloud Firestore หากการเชื่อมต่อ แต่ละฐานข้อมูลไม่เหมือนกัน โซลูชันนี้อาจรายงาน สถานะบุคคลไม่ถูกต้อง
- Android - ใน Android นั้น Realtime Database จะตัดการเชื่อมต่อจากแบ็กเอนด์หลังจากไม่มีการใช้งานเป็นเวลา 60 วินาที "ไม่มีการใช้งาน" จะทำให้ไม่มี Listener แบบเปิด
หรือการดำเนินการที่รอดำเนินการอยู่ เราขอแนะนําให้คุณเพิ่ม Listener เหตุการณ์ที่มีค่าลงในเส้นทางอื่นนอกเหนือจาก
.info/connected
เพื่อให้การเชื่อมต่อเปิดอยู่ ตัวอย่างเช่น คุณ สามารถทำFirebaseDatabase.getInstance().getReference((new Date()).toString()).keepSynced()
ที่จุดเริ่มต้นของแต่ละเซสชัน โปรดดูข้อมูลเพิ่มเติมที่หัวข้อการตรวจหาสถานะการเชื่อมต่อ