如何使用 Firestore 处理离线聚合?
How to handle offline aggregation using Firestore?
几天来我一直在网上搜索这个问题的解决方案。
即没有网络连接时如何处理聚合?我有一个任务管理应用程序,用于聚合有关用户任务的元数据。例如,任务可以包含标签,这些标签可以聚合以每天在仪表板中显示给用户。如果用户始终在线,这会很容易,所以我可以使用交易或云功能来聚合,但是当用户不在线时,聚合会出现错误,直到用户恢复他们的网络连接。
这里解释聚合查询:
https://firebase.google.com/docs/firestore/solutions/aggregation
其中规定了一个限制:
Offline support - Client-side transactions will fail when the user's
device is offline, which means you need to handle this case in your
app and retry at the appropriate time.
但是,还没有关于如何 'handle this case' 的任何示例或文档。我将如何解决这个问题?
一些想法:
如果交易失败,我可以缓存项目。该项目将在存储的聚合之上聚合。但是,沿着这条线走下去意味着我无法利用 Firestore 的“离线模式”,因为我在离线时每次写入时都使用自己的缓存。
我可以按需汇总。也就是说,永远不要存储聚合。根据用户有多少任务,这将是非常繁重的阅读。此外,如果聚合需要作为见解共享给其他用户,则此选项将不起作用,因为其他用户无权访问任务。
我很茫然,如有任何帮助,我们将不胜感激,谢谢!
经过大量的研究和反复试验,我找到了一个可以优雅地解决这个问题的解决方案。
FieldValue.increment 所做的是在尊重默认 Firestore 的离线缓存行为的同时绕过事务的使用。它需要直接在字段上使用设置或更新。缺点是无法在集合上使用 'withConverter' 来确保类型安全。考虑到 FieldValue.increment 的用处,我愿意忍受这个缺点。
我已经进行了多次测试,可以确认离线时本地值可以 incremented/decremented 多次。此离线值反映在对缓存的获取或快照调用中。当网络连接恢复时,值会在服务器上更新。
值本身不存储在缓存中,它只是将“差异”存储在 FieldValue 标记中,以便在服务器上更新它时使用。
此方法仅适用于递增和递减值。使用此方法无法存储平均值。这是因为在离线计算时不知道真正的项目总数。
相反,项目总数与总价值一起存储。然后根据需要计算平均值。这样,离线时从本地角度来看,平均值始终是准确的,在线时当总值和计数已同步时,平均值也将是准确的。
几天来我一直在网上搜索这个问题的解决方案。
即没有网络连接时如何处理聚合?我有一个任务管理应用程序,用于聚合有关用户任务的元数据。例如,任务可以包含标签,这些标签可以聚合以每天在仪表板中显示给用户。如果用户始终在线,这会很容易,所以我可以使用交易或云功能来聚合,但是当用户不在线时,聚合会出现错误,直到用户恢复他们的网络连接。
这里解释聚合查询:
https://firebase.google.com/docs/firestore/solutions/aggregation
其中规定了一个限制:
Offline support - Client-side transactions will fail when the user's device is offline, which means you need to handle this case in your app and retry at the appropriate time.
但是,还没有关于如何 'handle this case' 的任何示例或文档。我将如何解决这个问题?
一些想法:
如果交易失败,我可以缓存项目。该项目将在存储的聚合之上聚合。但是,沿着这条线走下去意味着我无法利用 Firestore 的“离线模式”,因为我在离线时每次写入时都使用自己的缓存。
我可以按需汇总。也就是说,永远不要存储聚合。根据用户有多少任务,这将是非常繁重的阅读。此外,如果聚合需要作为见解共享给其他用户,则此选项将不起作用,因为其他用户无权访问任务。
我很茫然,如有任何帮助,我们将不胜感激,谢谢!
经过大量的研究和反复试验,我找到了一个可以优雅地解决这个问题的解决方案。
FieldValue.increment 所做的是在尊重默认 Firestore 的离线缓存行为的同时绕过事务的使用。它需要直接在字段上使用设置或更新。缺点是无法在集合上使用 'withConverter' 来确保类型安全。考虑到 FieldValue.increment 的用处,我愿意忍受这个缺点。
我已经进行了多次测试,可以确认离线时本地值可以 incremented/decremented 多次。此离线值反映在对缓存的获取或快照调用中。当网络连接恢复时,值会在服务器上更新。
值本身不存储在缓存中,它只是将“差异”存储在 FieldValue 标记中,以便在服务器上更新它时使用。
此方法仅适用于递增和递减值。使用此方法无法存储平均值。这是因为在离线计算时不知道真正的项目总数。
相反,项目总数与总价值一起存储。然后根据需要计算平均值。这样,离线时从本地角度来看,平均值始终是准确的,在线时当总值和计数已同步时,平均值也将是准确的。