检测客户端代码中 Firestore db 节点的更改
Posted
技术标签:
【中文标题】检测客户端代码中 Firestore db 节点的更改【英文标题】:Detect changes in Firestore db node within client side code 【发布时间】:2018-11-30 09:29:34 【问题描述】:您能告诉我如何在客户端代码(.ts
文件)中检测 Firestore db 节点的变化吗?我知道如何使用云功能做到这一点。但是如何在客户端代码中做到这一点?
Firestore 节点: projects/id/transactions/
我的要求是这样的:如果以上节点有任何变化,我需要升级提供者(即projectProvider
)的共享属性值。我该怎么做?
举个例子:
onWrite
事件非常适合我的用例。但是如何在客户端.ts
文件中实现它呢?
这是node.js
云功能的实现。如何在客户端.ts
文件上进行这样的实现?
// Listen for any change on document `marie` in collection `users`
exports.myFunctionName = functions.firestore
.document('users/marie').onWrite((change, context) =>
// ... Your code here
);
注意:我将angularfire2
与我的ionic 3
应用程序一起使用。
【问题讨论】:
是否有充分的理由不为此使用 Cloud Functions?您可以使用 Node 中的 Web/javascript SDK 来收听使用onSnapshot
的集合。您也可以使用 Admin SDK 执行此操作。但是,Javascript SDK 有一个名为querySnapshot
的属性docChanges
。这将允许您仅过滤已更改的文档并处理这些文档。如果这适合您的需要,我可以发布一些示例代码。
我了解云功能及其功能。但是我的用例在这里有所不同。如果firestore db有任何变化,我需要更新本地属性。所以我不能使用云功能,因为它不能访问客户端属性(.ts
)。我们不能在客户端代码中调用onWrite
事件吗?我看到call functions
直接方法。但它仅适用于HTTPS callable function
。 @JasonBerryman firebase.google.com/docs/functions/callable
可调用函数允许您从客户端应用程序中调用函数。它们不允许您像 Cloud Functions 那样监控其他客户端对数据库的更改。如果有帮助,我可以发布一些代码,让您可以监控集合并通知您更改。
是的,请继续说。谢谢@JasonBerryman
【参考方案1】:
我的解决方案
第 1 步。 在 firestore 中,为您要通知客户端的任何信息制作通知文档。像这样的:
db.collection('notifications').doc('transactionHappened').set(/*your transaction details*/);
第 2 步。 注册到您的通知文档并收听它,例如当你在写一个交易文档时,也要将你最新的交易信息写入到transactionHappened doc中:
const yourHandler = data=>/*handle your notification details here*/;
db.collection('notifications').doc('transactionHappened').onSnapshot(yourHandler);
第 3 步。 现在 onSnapshot
已注册,但如果您的应用已断开连接,则在此期间它不会收到任何通知。让我们处理它。
const reconnectHandler =()=>/*you were offline, so read whatever you need from firestore to cath up with the latest data*/;
const disconnectHandler =()=>/*display something on your screen to indicate it is offline*/;
const monitorNetwork=()=>
let status = true;
const timeout = ()=> setTimeout(()=>
if(status !== navigator.onLine)
status = navigator.onLine;
console.log(`Network is $status? 'up ?':'down ?'`);
if (status) //if network is flipped to online
reconnectHandler();
else //just went offline
disconnectHandler();
timeout();
, 1000);
timeout();
上面的小功能会每1秒为你创建一个心跳来监控你的网络状态。
【讨论】:
【参考方案2】:部分解决方案
以下代码将允许您收听单个集合。目前没有办法跨多个项目文档收听子集合。对此的最佳解决方案是对您的数据模型进行反规范化,以便您拥有一个名为 projectTransactions
的集合,并使用 projectId
字段过滤客户端查询,并使用安全规则强制访问。
代码使用docChanges
方法,该方法允许您仅查看对集合所做的更改,而无需查看每个文档。这种方法在"View changes between snapshots" section of the documentation 中讨论过
查看查询快照之间查询结果的实际变化通常很有用,而不是简单地使用整个查询快照。
const firebase = require('firebase');
require("firebase/firestore");
// Initialize Firebase
let config =
apiKey: "*** Your API key ***",
authDomain: "*** Your Auth domain ***",
databaseURL: "*** Your database URL ***",
projectId: "*** Your project ID ***",
messagingSenderId: "*** Your Messaging Sender ID ***"
;
firebase.initializeApp(config);
let email = 'my.name@example.com';
let password = 'myExamplePassword';
firebase.auth().signInWithEmailAndPassword(email, password)
.catch(error =>
console.log(error);
);
firebase.auth().onAuthStateChanged((user) =>
if (user)
console.log('I am logged in');
// Initialise Firestore
const firestore = firebase.firestore();
const settings = timestampsInSnapshots: true;
firestore.settings(settings);
return firestore
.collection('projectTransactions')
.onSnapshot((querySnapshot) =>
console.log('Listening to the projectTransactions collection');
querySnapshot.docChanges().forEach((change) =>
// A new transaction has been added
if (change.type === 'added')
console.log(`A new transaction has been added with ID: $change.doc.id`);
// A transaction has been deleted
if (change.type === 'removed')
console.log(`A transaction has been removed with ID: $change.doc.id`);
);
);
else
// User is signed out.
// ...
);
【讨论】:
其实这不是我需要的。我需要订阅onWrite
事件。看来我们不能通过客户端代码做到这一点?
还有change.type === 'modified'
。这些change.type
属性是您可以获得的最接近的属性。以上是关于检测客户端代码中 Firestore db 节点的更改的主要内容,如果未能解决你的问题,请参考以下文章