我有一个表格来创建一个新的联系人,其中还包括一个“创建”按钮。当点击这个按钮,我希望表单进入只读模式,并在创建成功后,我想重定向到与新联系人相关的页面。
进入readonly可以正常工作,但是我在离线设置中遇到了重定向的问题。下面的createButton代码可以在在线设置中工作,其中createButton位于一个包含状态“pending”的有状态小部件中:
setState(() {
pending = true;
});
FirebaseFirestore.instance.collection(...).withConverter(...).add(contact).then((addedContact) {
setState(() {
pending = false;
});
context.goNamed('contact', params: {'contactId' : addedContact.id});
});
但是在脱机设置中,有关相关集合的侦听器都将使用新联系人进行更新,但此回调永远不会解析。
我目前考虑手动生成一个id,监听集合,并在创建具有该id的对象时重定向,但对于这种情况有什么最佳实践吗?
可能相关:我将其作为Web应用程序进行测试,并在初始化时执行以下调用:
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
await FirebaseFirestore.instance.enablePersistence(const PersistenceSettings(synchronizeTabs: true));
await FirebaseFirestore.instance.disableNetwork();
1条答案
按热度按时间yr9zkbsy1#
您所描述的是预期的行为。
then
侦听器仅在文档写入服务器后才会被调用,而当您离线时不会发生这种情况。完整行为如下所示:
add
的调用本身完成,则写入操作被提交到本地缓存,并且如果/当连接可用时,将与服务器同步。add
的调用本身引发异常,则本地写操作失败并被中止(这种情况很少见)。then
块被调用,则数据被写入服务器。Future
被拒绝(并且catch
块被执行),则数据在服务器上被拒绝-通常是因为您的安全规则,但请检查您得到的错误以确定原因。也可以在这里看到我的答案:Firestore setDoc -响应未定义
因此,当前代码只在数据写入服务器后才调用
setState
。如果你想在数据写入本地缓存后运行它,你不应该使用then
块,而是直接在add
调用后运行代码:这意味着状态会很短暂地挂起,因为本地写入会很快完成。我经常瞄准一个类似于WhatsApp的UI来显示状态,例如当数据在本地写入时显示一个复选标记,当数据也被提交到服务器时显示一个双复选标记。
最后,要在离线设置中获取文档的ID,请查看添加文档的文档中第三个代码示例中的以下代码:
您对
add(...)
的调用在此处分为两个:doc()
,它生成新的唯一ID,是一个纯客户端操作,也可以脱机工作。set(...)
,它实际上写入数据。因此,在上面的代码中,您可以从
newCityRef.id
获取新的ID。