Firebase RTDB:离线时调用keepSynced



我正在研究一个使用Firebase RTDB的Flutter应用程序。我对keepSynced()的机制有点不清楚:

我们的应用程序创建新的集合并向这些集合添加数据。该应用程序还观察这些集合以显示数据。在此过程中,我们调用keepSynced(true)以保持这些查询的离线缓存活动。现在我们注意到,当创建一个新的集合+在离线时调用keepSynced(true)时,我们在新集合上注册的侦听器直到应用程序再次上线才接收数据。从那时起,缓存和更新侦听器按预期工作(在线+离线)。

因此,在代码中:
// Execute this while offline:
// Enable permanent offline sync for a new node that doesn't exist yet on the Firebase server
await database.ref().child('new_node').keepSynced(true);
// Register listener
database.ref().child('new_node').onValue.listen((event) => print(event));
// Add data
database.ref().child('new_node/child').set({'key': 'value'});

设备上线后,监听器才会触发。

关于keepSynced()状态的文档

通过在一个位置上调用keepSynced(true),该位置的数据将自动下载并保持同步,即使没有为该位置附加侦听器。此外,当一个位置保持同步时,它不会从持久磁盘缓存中被删除。

所以它实际上需要与Firebase后端连接("将自动下载"),而调用keepSynced()为了离线缓存/查询工作?

您可以在任何时候调用keepSynced,但是客户端只有在连接到服务器时才能从服务器下载数据。

如果这不是你观察到的行为,请编辑你的问题,包括一个最小的重现。


更新基于你问题中的新版本:

你看到的行为是不幸的,但在意料之中。

Firebase API保证(这些天没有记录)它永远不会向你的应用程序显示部分节点。因为你只设置了/new_node/child,它不知道/new_node的当前状态,它不会在new_node上引发value事件,因为它只有关于该节点的部分信息。

如果您在new_node上监听child_added, SDK将在这种情况下引发一个事件——但它不会引发一个值事件,因为它直到可以确定它有new_node的完整快照。

最常见的两个路径是:

  • 在JSON树的较低级别侦听,例如侦听child_*事件(如上所述)。
  • 在所有new_node上执行初始写操作,以便本地SDK知道节点的预期初始状态是什么,然后可以执行低级写操作。如果存在无法擦除的数据,则可以使用安全规则拒绝服务器上的这个启动写操作。

最新更新