Flutter中Firebase Firestore数据操作失效 提示Something went wrong
Flutter Firestore实时集合监听加载失败问题
问题背景
实现逻辑为监听Firebase Firestore的msgerstory集合实时快照,通过StreamBuilder搭配ListView渲染每条文档的usrid字段,对应业务代码如下:
class _HomePageState extends State<HomePage> { final Stream<QuerySnapshot> _usersStream = FirebaseFirestore.instance.collection('msgerstory').snapshots(); @override Widget build(BuildContext context) { return Scaffold( body: StreamBuilder<QuerySnapshot>( stream: _usersStream, builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) { if (snapshot.hasError) { return Text('Something went wrong'); } if (snapshot.connectionState == ConnectionState.waiting) { return Text("Loading"); } return ListView( children: snapshot.data!.docs.map((DocumentSnapshot document) { Map<String, dynamic> data = document.data()! as Map<String, dynamic>; return ListTile( title: Text(data['usrid']), ); }).toList(), ); }, ), ); } }
报错现象
在x86架构Android模拟器以debug模式运行时,页面未加载预期列表数据,直接显示Something went wrong错误提示,控制台输出日志如下:
Launching lib\main.dart on Android SDK built for x86 in debug mode... Running Gradle task 'assembleDebug'... √ Built build\app\outputs\flutter-apk\app-debug.apk. Debug service listening on ws://127.0.0.1:53782/-K_CbrO9z_A=/ws Syncing files to device Android SDK built for x86... I/FirebaseApp(12073): Device unlocked: initializing all Firebase APIs for app [DEFAULT] I/flutter (12073): User is signed in! W/GooglePlayServicesUtil(12073): Google Play services out of date for com.rmessenger.rmessenger. Requires 11925000 but found 11743470 E/GooglePlayServicesUtil(12073): GooglePlayServices not available due to error 2 W/Firestore(12073): (24.1.2) [GrpcCallProvider]: Failed to update ssl context: com.google.android.gms.common.GooglePlayServicesRepairableException: Google Play Services not available D/NetworkSecurityConfig(12073): No Network Security Config specified, using platform default W/art (12073): Before Android 4.1, method double java.util.concurrent.ThreadLocalRandom.internalNextDouble(double, double) would have incorrectly overridden the package-private method in java.util.Random W/art (12073): Before Android 4.1, method int java.util.concurrent.ThreadLocalRandom.internalNextInt(int, int) would have incorrectly overridden the package-private method in java.util.Random W/art (12073): Before Android 4.1, method long java.util.concurrent.ThreadLocalRandom.internalNextLong(long, long) would have incorrectly overridden the package-private method in java.util.Random D/EGL_emulation(12073): eglMakeCurrent: 0xb1b85900: ver 2 0 (tinfo 0x92991980) W/Firestore(12073): (24.1.2) [Firestore]: Listen for Query(target=Query(msgerstory order by __name__);limitType=LIMIT_TO_FIRST) failed: Status{code=PERMISSION_DENIED, description=Missing or insufficient permissions., cause=null}
问题根因
日志排查确认两个核心问题:
- 模拟器内置Google Play Services版本不满足Firestore依赖要求:Firestore需11925000及以上版本,当前模拟器仅预装11743470版本,导致Firestore SSL上下文初始化失败,基础网络通信链路异常
- Firestore安全规则拦截请求:
msgerstory集合的监听请求返回PERMISSION_DENIED状态码,当前请求身份无对应集合的读取权限,请求被直接拒绝,最终触发StreamBuilder的错误分支渲染
修复步骤
1. 解决模拟器Google Play Services版本过低问题
- 方案一:打开Android Studio设备管理器,删除当前旧版x86模拟器,新建模拟器时选择带Google Play支持的最新x86_64系统镜像,这类镜像默认预装符合版本要求的Google Play Services,且支持在模拟器内通过Play商店直接更新服务版本
- 方案二:若保留现有模拟器,直接打开模拟器内的Google Play商店,搜索Google Play Services更新到最新版本,重启应用即可
2. 调整Firestore安全规则
进入Firebase控制台对应项目的Firestore数据库规则面板,根据业务需求配置访问权限。开发调试阶段已存在登录态的场景下,可临时使用以下规则快速验证:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /msgerstory/{document=**} { allow read: if request.auth != null; allow write: if request.auth != null; } } }
注意:正式上线前必须根据实际业务权限逻辑收紧规则,禁止长期开放全量读写权限,避免数据泄露与恶意写入
3. 代码健壮性优化
现有代码未做字段空兼容,当文档不存在usrid字段时会触发空指针崩溃,可调整字段读取逻辑增加兜底:
return ListTile( title: Text(data['usrid']?.toString() ?? '默认用户ID'), );
内容的提问来源于stack exchange,提问作者Raihan Hossain
相关产品推荐
相关产品推荐

