发送有关Firestore文档字段更改的推送通知

时间:2019-06-19 14:48:51

标签: node.js google-cloud-firestore firebase-cloud-messaging google-cloud-functions

我有一个Flutter应用程序,该应用程序允许用户使用Firestore RTDB互相租用物品。在我的租赁文件中,我有一个字段status,用于确定租赁状态(例如,像运送物品一样,物品的状态可以为“已订购”,“已发货”,“已交付”等)。我的status变量是一个介于0到5之间的数字,每个数字代表一个不同的阶段。当status变量更改时,我想通过推送通知来通知租借中的其他用户。但是我不知道以下哪种方法最好。

  1. 第一种方法是使用云功能,该功能在每次更新租赁文件时都会触发。但是我只检查status字段。看起来像这样:

    exports.notify = functions.firestore.document('rentals/{rentalId}')
    .onUpdate(async (snapshot, context) => {
        const oldSnap = snapshot.before.data(); // previous document        
        const newSnap = snapshot.after.data(); // current document       
    
        // status changes from 0 to 1
        if (oldSnap.status === 0 && newSnap.status === 1) {
            // do something
        }
    })
    

    我可以想到的一个缺点是,我必须做另一遍读取才能获得另一个用户的设备推送令牌。另外,对于每个租赁文件更新,此云功能都会触发,最终甚至根本不需要执行

  2. 另一种方法是拥有一个存储通知的notifications集合,并具有一个云功能,该云功能在添加新的通知文档时触发。然后,在客户端,当用户点击按钮时,更新租借中的status并创建新的通知文档。

    Firestore.instance
        .collection('rentals')
        .document(rentalId)
        .updateData({'status': newStatus});
    
    Firestore.instance.collection('notifications').add({
      'title': title,
      'body': body,
      'pushToken': <TOKEN HERE>,
    });
    

    与方法1相比,它执行了额外的写入操作,而不是读取操作。

哪种方法更好?

1 个答案:

答案 0 :(得分:1)

从技术上讲,这两种方法都是可行的并且有效。您选择哪种选择取决于用例,并且(取决于两者都可以在此处使用)取决于个人喜好。因此,我仅在下面简单强调几个关键差异,并解释何时我个人选择使用哪个差异。

您描述的第一种方法是将数据库视为状态机,其中每个状态和状态转换都有特定的含义。然后,您可以使用Cloud Functions在状态转换中触发代码。

第二种方法将数据库视为队列,其中数据的存在指示需要发生的情况。因此,Cloud Functions然后触发了文档的简单存在。

我通常使用基于队列的方法来进行生产工作,因为这样可以很容易地看到还有多少工作要做。 notifications集合中的所有内容都是需要发送的通知。

在状态转换数据模型中,要轻松查看此信息要困难得多。实际上,您需要在文档中添加额外的字段,以便能够获得“待处理的通知”列表。例如:带有待处理通知的租赁是状态从0更改为1的时间戳(您需要添加的字段,例如status_1_timestamp)比上次发送通知的时间戳(a notification_timestamp之类的字段。

但是我有时也使用状态转换方法。通常,当我要转换现有文档时,或者因为这只是一个很酷的用例而显示时(在大多数情况下,Firebase / Firestore SDK不会同时暴露旧状态和新状态)。

我可能会在这里选择基于队列的方法,但是如前所述:基于上述推理,这是我的个人偏好。如果这些原因不适用于您,或者您有其他原因,也可以。