Flutter从Firebase提取数据时遇Google Play服务相关错误求助
问题描述
实现了一个通过StreamBuilder展示Firebase Firestore中登录用户数据的Flutter页面,遇到两类问题:
- 初始设备触发Google Play服务缺失错误,日志信息:
W/GooglePlayServicesUtil( 3777): .................. requires the Google Play Store, but it is missing.
E/GooglePlayServicesUtil( 3777): GooglePlayServices not available due to error 9
W/Firestore( 3777): (24.4.2) [GrpcCallProvider]: Failed to update ssl context: com.google.android.gms.common.GooglePlayServicesNotAvailableException
- 更换为Google Pixel 2设备后,出现ProviderInstaller相关警告:
W/ProviderInstaller( 5334): Failed to report request stats: com.google.android.gms.common.security.ProviderInstallerImpl.reportRequestStats [class android.content.Context, long, long]
核心业务代码:
return Scaffold( appBar: AppBar( title: const Text("Your upcoming appointments"), ), body: SafeArea( child: Column( children: [ StreamBuilder( stream: FirebaseFirestore.instance.collection('client_bookings_doc').where('email', isEqualTo: currentUser.currentUser!.email).snapshots(), builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) { if (snapshot.hasData) { return ListView.builder( itemCount: snapshot.data!.docs.length, shrinkWrap: true, itemBuilder: (context, i) { var data = snapshot.data!.docs[i]; print(data['email']); return Text(data['email']); }, ); } else { return const Text("error"); } }, ), ], ), ), );
解决方案
一、Google Play服务缺失(错误9)的处理
错误9对应SERVICE_MISSING,本质是设备缺少或不兼容Google Play服务,按设备类型处理:
- 模拟器场景:必须使用带Google Play标识的系统镜像(创建模拟器时选「Google Play」标签,而非「Google APIs」),旧模拟器直接删除重建。
- 实体设备场景:
- 确认设备已安装Google Play商店,未安装的设备需刷入含Google服务的官方ROM(仅限支持的机型)。
- 打开Google Play商店,检查并更新Google Play服务到最新版本。
- 项目配置检查:
确保android/app/build.gradle中依赖版本兼容:
同时dependencies { implementation platform('com.google.firebase:firebase-bom:32.7.0') implementation 'com.google.firebase:firebase-firestore' implementation 'com.google.android.gms:play-services-base:18.2.0' }android/build.gradle需配置Google服务插件:buildscript { dependencies { classpath 'com.google.gms:google-services:4.4.0' } }
二、ProviderInstaller警告的处理
该警告多因设备安全提供器版本过旧或Google Play服务更新不完整,可按以下方式处理:
- 强制更新安全提供器:在项目启动时添加代码触发更新:
需在import 'package:google_api_availability/google_api_availability.dart'; import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); // 检查并修复Google Play服务状态 final availability = await GoogleApiAvailability.instance.checkGooglePlayServicesAvailability(); if (availability != GooglePlayServicesAvailability.success) { await GoogleApiAvailability.instance.makeGooglePlayServicesAvailable(); } // 触发安全提供器更新 try { await MethodChannel('com.google.android.gms.security.ProviderInstaller') .invokeMethod('installIfNeeded'); } on PlatformException catch (e) { print('ProviderInstaller 更新失败: ${e.message}'); } runApp(const MyApp()); }pubspec.yaml添加依赖:dependencies: google_api_availability: ^5.0.0 - 系统更新:将Pixel 2设备系统升级到最新版本,确保安全组件同步更新。
- 忽略警告:若不影响核心功能,可暂时忽略,后续Google Play服务更新后可能自动修复。
代码优化建议
原代码存在空指针风险,建议添加空安全处理:
stream: FirebaseFirestore.instance .collection('client_bookings_doc') .where('email', isEqualTo: currentUser.currentUser?.email ?? '') .snapshots(),
同时完善StreamBuilder的状态处理:
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } if (snapshot.hasError) { return Text('加载错误: ${snapshot.error}'); } if (!snapshot.hasData || snapshot.data!.docs.isEmpty) { return const Text("暂无预约数据"); } return ListView.builder( itemCount: snapshot.data!.docs.length, shrinkWrap: true, itemBuilder: (context, i) { var data = snapshot.data!.docs[i]; return Text(data['email'] ?? '无邮箱数据'); }, ); },
内容的提问来源于stack exchange,提问作者flutter_dev

