这个问题是对Firestore offline cache的后续行动。我已经阅读了离线缓存documentation,但有一点感到困惑。
一位评论者回答了前一个问题(〜一年前):
无论您是否连接,与数据库交互的Android代码都是相同的,因为SDK的工作原理相同。“
在API documentation for DocumentReference's set method,我只是注意到它说:
返回
non-null Promise containing void
数据成功写入后端后解析的promise。 (请注意,在您离线时无法解决此问题)。
强调我的。文档中的这一点是否表明代码不会表现相同,或者我错过了什么?如果我在允许某些用户交互之前等待.set()解决,那么从这一点来看,我需要调整离线情况的代码,这与我通常不同。
CollectionReference's add method让我更担心。它没有完全相同的音符但是说(强调我的):
在将DocumentReference写入后端后,使用DocumentReference解析指向新创建的文档的Promise。
这有点模糊,因为不确定在这种情况下“后端”是否是“缓存”和“服务器”的超集,或者它是否仅表示服务器。如果这个没有解决,那将意味着以下不起作用,对吗?
return new Promise((resolve, reject) => {
let ref = firestore.collection(path)
ref.add(data)
.then(doc => {
resolve({ id: doc.id, data: data })
})
...
})
意思是.add()无法解析,.then()不会运行,我也无法访问刚刚添加的文档的id
。我希望我只是误解了一些东西,我的代码可以继续在线和离线运行。
你有两个关注点,它们并不是真正相关的。我将分别解释它们。
在大多数情况下,开发人员通常不关心文档更新的承诺是否实际解决。它几乎总是“火与忘记”。只要应用程序以相同的方式运行,应用程序会知道更新是否会对服务器产生什么影响?本地缓存已更新,并且所有将来的查询都将显示文档已更新,即使更新尚未与服务器同步。
对此的主要例外是交易。 Transactions要求服务器在线,因为需要在客户端和服务器之间进行往返,以确保更新是原子的。交易根本无法脱机工作。如果您需要知道交易是否有效,您需要在线。与普通文档写入不同,事务不会在本地缓存中持久存在。如果应用程序在服务器上的事务完成之前被终止,则事务将丢失。
您的第二个问题是新添加的文档,其中更新时未定义文档的ID。确实,add()
返回的承诺只有在服务器上存在新文档时才能解析。在承诺为您提供新文档的DocumentReference
之前,您无法知道文档的ID。
如果此行为不适合您,则可以通过简单地调用不带参数的doc()
而不是add()
来为文档生成新的id。 doc()
立即返回未写入的新(未来)文档的DocumentReference(直到您选择编写它)。在doc()
和add()
的情况下,这些DocumentReference对象包含在客户端上生成的唯一ID。区别在于使用doc()
,您可以立即使用id,因为您可以立即获得DocumentReference。使用add()
,你不能,因为在promise解析之前不提供DocumentReference。如果您现在需要新的文档ID,即使在离线时,也请使用doc()
而不是add()
。然后,您可以使用返回的DocumentReference创建脱机文档,存储在本地缓存中,并在以后进行同步。然后,更新将返回一个在实际写入文档时解析的promise。