視您所開發的應用程式類型而定,您可能會發現 哪些使用者或裝置經常在線上 (也就是 偵測是否「存在」
舉例來說,如果您正在建構像是社交網路之類的應用程式 就能顯示一系列 可以免費進行即時通訊的好友,或按照 「上次上線」。
Cloud Firestore 並未原生支援在家狀態,但您可以 利用其他 Firebase 產品打造行動體系。
解決方案:Cloud Functions 搭配即時資料庫
將 Cloud Firestore 連結至 Firebase 即時資料庫的原生 此時請使用 Cloud Functions
透過即時資料庫回報連線狀態,然後使用 Cloud Functions 來 以複製資料至 Cloud Firestore
使用即時資料庫的在家狀態功能
首先,請思考即時資料庫傳統在家狀態系統的運作方式。
網路
// 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); }); });
這個範例是完整的即時資料庫存在系統。處理 許多連線中斷、當機等等
連線至 Cloud Firestore
如要在 Cloud Firestore 中導入類似的解決方案,請使用 接著是即時資料庫程式碼,接著使用 Cloud Functions 保留即時資料庫 同步 Cloud Firestore
如果您尚未將即時資料庫新增至專案,請先完成這項操作 並納入上述業務解決方案
接著請將目前狀態與 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}
文件,並使用這項資料變更使用者介面,以反映連線
狀態。
網路
userStatusFirestoreRef.onSnapshot(function(doc) { var isOnline = doc.data().state == 'online'; // ... use isOnline });
全域更新 Cloud Firestore
雖然我們的應用程式確實能正確回報線上上線,但是這個狀態
我們的「離線」服務仍將不準確
狀態寫入作業僅能在本機環境中寫入,恢復連線後就不會同步。給計數器
這將會使用 Cloud 函式即時監控 status/{uid}
路徑
資料庫。當即時資料庫值變更時,值就會同步至 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); // ... } }); });
限制
如何使用即時資料庫將即時資料庫新增至 Cloud Firestore 應用程式: 可彈性擴充並有效,但有一些限制:
- 去彈跳 - 監聽即時變更 在 Cloud Firestore 中,這項解決方案可能會觸發 並輸入變更內容如果這些變更觸發的事件數量超出您的預期,請手動 處理 Cloud Firestore 事件。
- 連線能力:這種實作方式會評估與 Realtime 的連線能力 而非 Cloud Firestore如果連線 每個資料庫的狀態都不同,這項解決方案可能會回報 狀態不正確
- Android - 在 Android 上,即時資料庫會從
並在閒置 60 秒後載入後端閒置時表示沒有開啟事件監聽器
或待處理的作業為確保連線保持開啟,建議您新增
對
.info/connected
以外路徑的值事件監聽器。舉例來說, 可FirebaseDatabase.getInstance().getReference((new Date()).toString()).keepSynced()
在每個工作階段開始時啟動若需更多資訊,請參閲 偵測連線狀態。