Flutter Firebase中Facebook登录后读取Google Fitness API睡眠数据问题
Flutter Firebase Facebook登录后无法读取Google Fitness睡眠数据问题
我们基于Flutter开发一款睡眠数据仪表盘应用,通过Firebase实现社交登录,支持谷歌、Facebook及邮箱/密码三种登录方式。
谷歌登录正常情况
使用谷歌账号登录时,应用可正常获取睡眠数据,我们通过在GoogleSignIn中传入权限范围实现:
FirebaseAuth.instance, UserRepository(), GoogleSignIn(scopes:[ 'https://www.googleapis.com/auth/fitness.sleep.read', ])),
Facebook登录后的错误
使用Facebook登录时,读取睡眠数据会持续抛出如下错误,核心困惑是不知道如何在Facebook登录流程中传入Google API权限范围:
W/FLUTTER_HEALTH::ERROR(31643): There was an error getting the sleeping data! W/FLUTTER_HEALTH::ERROR(31643): 4: The user must be signed in to make this API call. W/FLUTTER_HEALTH::ERROR(31643): [Ljava.lang.StackTraceElement;@7eb1aa0 W/FLUTTER_HEALTH::ERROR(31643): There was an error getting the sleeping data! W/FLUTTER_HEALTH::ERROR(31643): 4: The user must be signed in to make this API call. W/FLUTTER_HEALTH::ERROR(31643): [Ljava.lang.StackTraceElement;@ef740cc W/FLUTTER_HEALTH::ERROR(31643): There was an error getting the sleeping data! W/FLUTTER_HEALTH::ERROR(31643): 4: The user must be signed in to make this API call. W/FLUTTER_HEALTH::ERROR(31643): [Ljava.lang.StackTraceElement;@abd9db8
当前读取睡眠数据的代码
Future fetchSleepData() async { List<HealthDataPoint> _healthDataList = []; final types = [ HealthDataType.SLEEP_ASLEEP, HealthDataType.SLEEP_AWAKE, HealthDataType.SLEEP_IN_BED ]; final permissions = [ HealthDataAccess.READ, HealthDataAccess.READ, HealthDataAccess.READ ]; final now = DateTime.now(); final yesterday = now.subtract(Duration(days: 10)); HealthFactory health = HealthFactory(); bool requested = await health.requestAuthorization(types, permissions: permissions); await Permission.activityRecognition.request(); await Permission.location.request(); if (requested) { try { // fetch health data List<HealthDataPoint> healthData = await health.getHealthDataFromTypes(yesterday, now, types); // save all the new data points (only the first 100) _healthDataList.addAll((healthData.length < 100) ? healthData : healthData.sublist(0, 100)); } catch (error) { print("Exception in getHealthDataFromTypes: $error"); } // filter out duplicates _healthDataList = HealthFactory.removeDuplicates(_healthDataList); // print the results _healthDataList.forEach((x) => print(x)); } }
解决方案建议
核心逻辑明确
Google Fitness API仅接受Google账号的OAuth 2.0令牌认证,Facebook登录的凭证无法直接用于调用该API。无论用户用哪种方式登录Firebase,要读取Google睡眠数据,都需要额外完成Google账号的授权流程。具体实现步骤
- 当用户通过Facebook/邮箱登录后,首次进入睡眠数据页面时,触发Google账号授权流程,传入
fitness.sleep.read权限范围。 - 授权成功后,确保
HealthFactory使用Google的认证令牌进行API调用。
- 当用户通过Facebook/邮箱登录后,首次进入睡眠数据页面时,触发Google账号授权流程,传入
代码调整示例
在fetchSleepData执行前,先检查并获取Google授权:final GoogleSignIn _googleSignIn = GoogleSignIn(scopes: [ 'https://www.googleapis.com/auth/fitness.sleep.read', ]); Future<void> ensureGoogleAuth() async { if (!await _googleSignIn.isSignedIn()) { await _googleSignIn.signIn(); } }调用顺序调整为:先执行
ensureGoogleAuth(),再执行fetchSleepData()。用户体验优化
在Facebook登录后首次访问睡眠数据时,添加明确提示,告知用户需要关联Google账号以获取睡眠数据,避免授权弹窗过于突兀。
内容的提问来源于stack exchange,提问作者Ramesh Angamuthu
相关产品推荐
相关产品推荐

