我有一个Flutter应用程序,允许用户使用Firestore RTDB互相租用物品。在我的租赁文档中,我有一个确定租赁状态的字段status
(可以将其视为运送物品,其中物品可以具有"已订购"、"已发货"、"已交付"等状态)。我的status
变量是 0 到 5 之间的数字,每个数字代表一个不同的相位。当status
变量发生变化时,我想通过推送通知通知租赁中的其他用户。但我不知道以下哪种方法最好。
-
第一种方法是使用每次更新租赁文档时触发的云函数。但我只检查
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 } })
我能想到的一个缺点是我必须再次读取才能获得其他用户的设备推送令牌。此外,对于每个租赁文档更新,此云功能将触发,最终甚至可能不需要首先执行。
-
另一种方法是拥有一个存储通知的
notifications
集合,并具有在添加新通知文档时触发的云函数。然后,在客户端,当用户点击按钮时,更新租赁中的status
并创建新的通知文档。Firestore.instance .collection('rentals') .document(rentalId) .updateData({'status': newStatus}); Firestore.instance.collection('notifications').add({ 'title': title, 'body': body, 'pushToken': <TOKEN HERE>, });
与方法 1 相比,这将执行额外的写入而不是读取。
哪种方法更好?
这两种方法在技术上都是可行的,并且是有效的。选择哪一个取决于用例,并且(鉴于两者都可以在这里工作)取决于个人喜好。这就是为什么我将在下面简单地强调一些关键差异,并解释我个人何时选择使用哪一个。
您描述的第一种方法是将数据库视为状态机,其中每个状态和状态转换都有特定的含义。然后,使用云函数在状态转换中触发代码。
第二种方法将数据库视为队列,其中数据的存在指示需要发生的情况。因此,云函数随后会触发文档的简单存在。
我通常使用基于队列的方法进行生产工作,因为它可以很容易地看到还有多少工作要做。notifications
集合中的任何内容都是需要发送的通知。
在状态转换数据模型中,很难轻松查看此信息。实际上,您需要向文档添加额外的字段才能获得此"待处理通知"列表。例如:带有待处理通知的租赁是指状态从 0 更改为 1 的时间戳的租赁(您需要添加的字段,例如status_1_timestamp
) 小于上次发送通知的时间戳(类似于notification_timestamp
的字段)。
但我有时也会使用状态转换方法。通常是当我想转换现有文档时,或者因为它只是一个很酷的用例(因为在大多数情况下,Firebase/Firestore SDK 不会同时公开旧状态和新状态)。
我可能会在这里选择基于队列的方法,但如前所述:根据上述推理,这是我的个人偏好。如果这些原因不适用于您,或者您有不同的原因,那也可以。