Firestore ConnectionState 在颤振应用程序中永远处于等待状态

Posted

技术标签:

【中文标题】Firestore ConnectionState 在颤振应用程序中永远处于等待状态【英文标题】:Firestore ConnectionState is in Waiting state forever in flutter app 【发布时间】:2020-01-04 17:33:46 【问题描述】:

我正在尝试从 Firestore 数据库中获取记录并将其显示在 Flutter 应用中。

@override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
          title: Text('Hello'),
          actions: <Widget>[
            IconButton(icon: Icon(Icons.list), onPressed: _pushSaved)
          ]),
      drawer: _buildDrawer(),
      body: _buildCarpoolsList(),
    );
  

Widget _buildCarpoolsList() 
    return StreamBuilder<QuerySnapshot>(
        stream: Firestore.instance.collection("carpools").snapshots(),
        builder: (context, snapshot) 
          if (!snapshot.hasData) 
            return CircularProgressIndicator();
           else 
            var _carpools = snapshot.data.documents;
            return ListView(
                padding: const EdgeInsets.all(16.0),
                children: _deserializeCarpools(_carpools));
          
        );
  

_buildCarpoolsList() 函数中,snapshot.ConnectionState 始终为ConnectionState.waiting,并且该函数返回CircularProgressBar()

我在 FireStore 数据库中有一个集合 carpools,其中包含一些记录。

我已将 firestore 数据库规则设置为允许所有。

rules_version = '2';
service cloud.firestore 
  match /** 
      allow read, write: if true;
  

编辑:我的 Firebase 身份验证有效。 (如果有帮助的话)

这里可能缺少什么?

【问题讨论】:

愚蠢的问题 -> 你是否下载了google_services.json 文件并将其添加到你的项目中? 是的,我做到了。我正在开发 ios 模拟器。 我刚刚看到,对于 iOS,您需要一个不同的文件:pub.dev/packages/cloud_firestore,GoogleService-Info.plist。你也这样吗? 是的,我愿意。它已添加到我的 iOS 应用程序中,并且 Firebase 应用程序配置正确。 嗨!你找到解决办法了吗? 【参考方案1】:

如果您在 FlutterFire 上查看了Cloud Firestore,并且安全规则没有问题,请检查您是否正确使用了.map().forEach()

例如,以下内容运行良好:

builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) 

        List<String> urls = [];
        if (snapshot.hasError) 
          return ...
        

        if (snapshot.connectionState == ConnectionState.waiting) 
          return ...
        
        
        **snapshot.data.docs.forEach((QueryDocumentSnapshot document) 
          print(document);
          urls.add(...);
        );**

        return Container( 
          child: GridView.count(
            crossAxisCount: ...,
            childAspectRatio: (...),
            children: List.generate(urls.length, (index) 

但是,如果您的小部件应该使用 urls 中的项目显示一些图像,则以下示例不会执行任何操作:

builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) 

        List<String> urls = [];
        if (snapshot.hasError) 
          return ...
        

        if (snapshot.connectionState == ConnectionState.waiting) 
          return ...
        
        
        
        **snapshot.data.docs.map((QueryDocumentSnapshot document) 
          print(document);
          urls.add(...);
        );**

        return Container( 
          child: GridView.count(
            crossAxisCount: ...,
            childAspectRatio: (...),
            children: List.generate(urls.length, (index) 

虽然document 出现在两个示例中,但这并不意味着它们执行相同的操作。还值得注意的是,在加载过程中至少满足了一次条件snapshot.connectionState == ConnectionState.waiting,它让你认为你在永久等待。

【讨论】:

【参考方案2】:

我也遇到了同样的问题,我一直在关注 Flutter In focus 的指南。状态始终处于连接状态,没有返回数据,也没有错误。这是在 iOS 中,然后我在 android 中运行了该应用程序,幸运的是在 LogCat 中,我看到了一条消息 permission to listen to query was denied 默认情况下,安全规则似乎拒绝一切,你。正如@MSaudi 提到的那样,必须允许它。我添加了这个,它工作了

   match /collectionName/documentId 
       allow read, write : if collectionName == "products";
   

要使用安全规则,下面的链接会有所帮助

Firebase security rules

【讨论】:

【参考方案3】:

我遇到了同样的情况。使用 cloud_firestore 插件和 StreamBuilder :

class DealerWorkPage extends StatelessWidget 
final String wheelId;
DealerWorkPage(this.wheelId);
@override
Widget build(BuildContext context) 
return StreamBuilder(
    stream: Firestore.instance.collection('wheels').document(this.wheelId).snapshots(),

    builder: (context, asyncSnapshot) 
        if(asyncSnapshot.hasError) return Text('Error: $asyncSnapshot.error');

        switch (asyncSnapshot.connectionState) 
          case ConnectionState.none: return Center(child: Text('No data'));
          case ConnectionState.waiting: return Center(child: CircularProgressIndicator());
          case ConnectionState.active:
            return Center(child: Text(asyncSnapshot["description"]))
          break;
        
        return null;
    );
 

此代码运行没有错误,但只显示 CircularProgressIndicator() 永远!

我尝试了另一个带有 add 子句的颤振项目:

await _firestore.collection('messages').add(
    'text': messageController.text,
    'from': widget.user.email,
    'date': DateTime.now().toIso8601String().toString(),
  );

它抛出:PlatformException(执行 setData 时出错,PERMISSION_DENIED:缺少权限或权限不足

现在,就像@MSaudi 所说,这个错误与 firebase 安全规则有关。然后我在 Firebase 控制台中检查数据库安全规则。是的,我忘记“延长”数据库访问日期:

rules_version = '2';
service cloud.firestore 
match /databases/database/documents 

// This rule allows anyone on the internet to view, edit, and delete
// all data in your Firestore database. It is useful for getting
// started, but it is configured to expire after 30 days because it
// leaves your app open to attackers. At that time, all client
// requests to your Firestore database will be denied.
//
// Make sure to write security rules for your app before that time, or else
// your app will lose access to your Firestore database
match /document=** 
  allow read, write: if request.time < timestamp.date(2020, 1, 27);
  
 

将 request.time timestamp.date(2020, 1, 27) 更改为以后的日期后, 瞧!我的 StreamBuilder 的行为符合预期!。无需再等待! 我希望这些信息对您有所帮助。

【讨论】:

【参考方案4】:

您可以在Firebase 控制台中修改安全设置。 如果您在生产模式(不是测试)中创建了数据库,那么它带有可能会阻止任何连接的安全规则,直到您允许为止。

在数据库屏幕中打开Rules 选项卡,(仅用于测试-> 允许读取、写入;如下所示) 如果可行,请考虑阅读安全规则并根据您的需要进行适当设置。

rules_version = '2';
service cloud.firestore 
  match /databases/database/documents 
    match /document=** 
      allow read, write;
    
  

【讨论】:

【参考方案5】:

你是否在你的Runner.xcworkspace中添加了GoogleService-Info.plist,你必须用Xcode打开它。我总是忘记在新项目中添加它:

【讨论】:

以上是关于Firestore ConnectionState 在颤振应用程序中永远处于等待状态的主要内容,如果未能解决你的问题,请参考以下文章

AsyncSnapshot 状态始终为 connectionState.waiting

Flutter 中的 StreamBuilder 卡在 ConnectionState.waiting 中并且只显示加载标记

介绍开源的.net通信框架NetworkComms框架 源码分析ConnectionState

DB ConnectionState = Open 但 context.SaveChanges 抛出“连接中断”异常

在 Flutter 中具有加载小部件的提供程序 [重复]

WebRTC connectionState 停留在“new” - 仅适用于 Safari,适用于 Chrome 和 FF