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 抛出“连接中断”异常
WebRTC connectionState 停留在“new” - 仅适用于 Safari,适用于 Chrome 和 FF