我有一个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相比,它执行了额外的写入操作,而不是读取操作。
哪种方法更好?
答案 0 :(得分:1)
从技术上讲,这两种方法都是可行的并且有效。您选择哪种选择取决于用例,并且(取决于两者都可以在此处使用)取决于个人喜好。因此,我仅在下面简单强调几个关键差异,并解释何时我个人选择使用哪个差异。
您描述的第一种方法是将数据库视为状态机,其中每个状态和状态转换都有特定的含义。然后,您可以使用Cloud Functions在状态转换中触发代码。
第二种方法将数据库视为队列,其中数据的存在指示需要发生的情况。因此,Cloud Functions然后触发了文档的简单存在。
我通常使用基于队列的方法来进行生产工作,因为这样可以很容易地看到还有多少工作要做。 notifications
集合中的所有内容都是需要发送的通知。
在状态转换数据模型中,要轻松查看此信息要困难得多。实际上,您需要在文档中添加额外的字段,以便能够获得“待处理的通知”列表。例如:带有待处理通知的租赁是状态从0更改为1的时间戳(您需要添加的字段,例如status_1_timestamp
)比上次发送通知的时间戳(a notification_timestamp
之类的字段。
但是我有时也使用状态转换方法。通常,当我要转换现有文档时,或者因为这只是一个很酷的用例而显示时(在大多数情况下,Firebase / Firestore SDK不会同时暴露旧状态和新状态)。
我可能会在这里选择基于队列的方法,但是如前所述:基于上述推理,这是我的个人偏好。如果这些原因不适用于您,或者您有其他原因,也可以。