【问题标题】:Detect changes in Firestore db node within client side code检测客户端代码中 Firestore db 节点的更改
【发布时间】: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

标签: angular typescript firebase ionic3 google-cloud-firestore


【解决方案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 属性是您可以获得的最接近的属性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-29
    • 1970-01-01
    • 2018-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多