无法使用 Flutter 和 Firebase 设置 Facebook 身份验证

Posted

技术标签:

【中文标题】无法使用 Flutter 和 Firebase 设置 Facebook 身份验证【英文标题】:Unable to setup Facebook authentication with Flutter and Firebase 【发布时间】:2021-09-01 06:28:39 【问题描述】:

我正在尝试使用 Firebase 编写带有身份验证的登录页面。 我有正常工作的电子邮件和谷歌身份验证功能,但我坚持使用 Facebook 方法。

我按照 Facebook 的快速入门所说的做了一切:

1.添加到 app/build.gradle 依赖项

implementation 'com.facebook.android:facebook-android-sdk:[5,6)'

2.根据我的AndroidManifest.xml文件设置包名(带有change_app_package_name库)并在Developers Facebook站点中设置。

3. 使用命令在 Linux 上生成用于开发的 Key Hash:

keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64

4. 在 Firebase 控制台和 Developers.Facebook 中启用登录。

5. 在 android/app/src/main/res/values 中创建 strings.xml 文件,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name"> <MyAppName> </string>
    <string name="facebook_app_id"> <MyAppId> </string>
    <string name="fb_login_protocol_scheme"> fb<MyAppId> </string>
</resources>

6. 将所需内容添加到 AndroidManifest.xml。这是我的整个文件:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.tiver.app">
    <application
            android:label="Tiver"
            android:icon="@mipmap/ic_launcher">
        <activity
                android:name=".MainActivity"
                android:launchMode="singleTop"
                android:theme="@style/LaunchTheme"
                android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
                android:hardwareAccelerated="true"
                android:windowSoftInputMode="adjustResize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
            <meta-data
                    android:name="io.flutter.embedding.android.NormalTheme"
                    android:resource="@style/NormalTheme"
            />
            <meta-data
                    android:name="io.flutter.embedding.android.SplashScreenDrawable"
                    android:resource="@drawable/launch_background"
            />
        </activity>
        <meta-data
                android:name="flutterEmbedding"
                android:value="2" />

        <meta-data android:name="com.facebook.sdk.ApplicationId"
                   android:value="@string/facebook_app_id"/>

        <activity android:name="com.facebook.FacebookActivity"
                  android:configChanges=
                          "keyboard|keyboardHidden|screenLayout|screenSize|orientation"
                  android:label="@string/app_name" />
        <activity
                android:name="com.facebook.CustomTabActivity"
                android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="@string/fb_login_protocol_scheme" />
            </intent-filter>
        </activity>
    </application>
    <uses-permission android:name="android.permission.INTERNET"/>
</manifest>

我通过以下方式实现了我的 signInWithFacebook 函数:

@override
  Future<Either<AuthFailure, Unit>> signInWithFacebook() async 
    final result = await _facebookAuth.login();
    if (result.status == LoginStatus.success) 
      final credential =
          FacebookAuthProvider.credential(result.accessToken!.token);
      print(credential);
      try 
        await _firebaseAuth.signInWithCredential(credential);
        return right(unit);
       on PlatformException catch (error) 
        if (error.code == 'invalid-credential') 
          return left(const AuthFailure.invalidEmailOrPassword());
         else 
          return left(const AuthFailure.serverError());
        
      
    

    return left(const AuthFailure.cancelledByUser());
  

所有其他签名方法都以类似的方式实现,并且可以正常工作。 我使用 FacebookAuth.instance 的 _facebookAuth,在 getItInjectable 的帮助下 - 我在 injection.dart 文件中注册了它:

GetIt s1 = GetIt.instance;

Future<void> init() async 
  s1.registerLazySingleton(() => FacebookAuth.instance);

注入似乎是正确的,它不会记录任何错误,我认为它是正确执行单元测试所必需的。

在我的 Firebase 控制台中,我使用正确填写的 App Id 和 App Secret 启用了 Facebook 登录。我还使用了生成的 url 重定向并在我的 Facebook 应用程序仪表板中指定。

我仔细检查了我是否完成了身份验证所需的每一个步骤,研究了我收到的错误消息,但我仍然不知道为什么我仍然收到以下错误:

在应用初始化时发生。

HttpStatus: 400, errorCode: 100, subErrorCode: 33, errorType: GraphMethodException, errorMessage: Unsupported get request. Object with ID '<MyAppId>' does not exist, cannot be loaded due to missing permissions, or does not support this operation. Please read the Graph API documentation at https://developers.facebook.com/docs/graph-api

它发生在 Facebook 身份验证过程之后 - 我单击使用 facebook 登录按钮,我被重定向到 facebook 页面,我正确地看到我登录的应用程序名称,它将我重定向回我的登录应用程序中的页面并记录以下错误:

E/flutter ( 7488): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: Unhandled error [firebase_auth/invalid-credential] The supplied auth credential is malformed or has expired. [ Unsuccessful debug_token response from Facebook: "error":"message":"Error validating application. Cannot get application info due to a system error.","type":"OAuthException","code":190,"fbtrace_id":"ArGSne7K9z7tMuLSPceuJy8" ] occurred in Instance of 'SignInFormBloc'.
E/flutter ( 7488): #0      MethodChannelFirebaseAuth.signInWithCredential (package:firebase_auth_platform_interface/src/method_channel/method_channel_firebase_auth.dart:422:7)
E/flutter ( 7488): <asynchronous suspension>
E/flutter ( 7488): #1      FirebaseAuth.signInWithCredential (package:firebase_auth/src/firebase_auth.dart:465:7)
E/flutter ( 7488): <asynchronous suspension>
E/flutter ( 7488): #2      FirebaseAuthFacade.signInWithFacebook (package:food_informer/infrastructure/auth/firebase_auth_facade.dart:92:9)
E/flutter ( 7488): <asynchronous suspension>
E/flutter ( 7488): #3      SignInFormBloc.mapEventToState.<anonymous closure> (package:food_informer/application/auth/sign_in_form/sign_in_form_bloc.dart:62:22)
E/flutter ( 7488): <asynchronous suspension>
E/flutter ( 7488): 
E/flutter ( 7488): #0      BlocBase.onError.<anonymous closure> (package:bloc/src/bloc.dart:389:7)
E/flutter ( 7488): #1      BlocBase.onError (package:bloc/src/bloc.dart:390:6)
E/flutter ( 7488): #2      _rootRunBinary (dart:async/zone.dart:1378:47)
E/flutter ( 7488): #3      _CustomZone.runBinary (dart:async/zone.dart:1272:19)
E/flutter ( 7488): #4      _CustomZone.runBinaryGuarded (dart:async/zone.dart:1178:7)
E/flutter ( 7488): #5      _BufferingStreamSubscription._sendError.sendError (dart:async/stream_impl.dart:360:15)
E/flutter ( 7488): #6      _BufferingStreamSubscription._sendError (dart:async/stream_impl.dart:378:16)
E/flutter ( 7488): #7      _BufferingStreamSubscription._addError (dart:async/stream_impl.dart:280:7)
E/flutter ( 7488): #8      _SyncBroadcastStreamController._sendError.<anonymous closure> (dart:async/broadcast_stream_controller.dart:393:20)
E/flutter ( 7488): #9      _BroadcastStreamController._forEachListener (dart:async/broadcast_stream_controller.dart:323:15)
E/flutter ( 7488): #10     _SyncBroadcastStreamController._sendError (dart:async/broadcast_stream_controller.dart:392:5)
E/flutter ( 7488): #11     _BroadcastStreamController._addError (dart:async/broadcast_stream_controller.dart:290:5)
E/flutter ( 7488): #12     _rootRunBinary (dart:async/zone.dart:1378:47)
E/flutter ( 7488): #13     _CustomZone.runBinary (dart:async/zone.dart:1272:19)
E/flutter ( 7488): #14     _CustomZone.runBinaryGuarded (dart:async/zone.dart:1178:7)
E/flutter ( 7488): #15     _BufferingStreamSubscription._sendError.sendError (dart:async/stream_impl.dart:360:15)
E/flutter ( 7488): #16     _BufferingStreamSubscription._sendError (dart:async/stream_impl.dart:378:16)
E/flutter ( 7488): #17     _BufferingStreamSubscription._addError (dart:async/stream_impl.dart:280:7)
E/flutter ( 7488): #18     _ForwardingStreamSubscription._addError (dart:async/stream_pipe.dart:128:11)
E/flutter ( 7488): #19     _ForwardingStream._handleError (dart:async/stream_pipe.dart:95:10)
E/flutter ( 7488): #20     _ForwardingStreamSubscription._handleError (dart:async/stream_pipe.dart:157:13)
E/flutter ( 7488): #21     _rootRunBinary (dart:async/zone.dart:1378:47)
E/flutter ( 7488): #22     _CustomZone.runBinary (dart:async/zone.dart:1272:19)
E/flutter ( 7488): #23     _CustomZone.runBinaryGuarded (dart:async/zone.dart:1178:7)
E/flutter ( 7488): #24     _BufferingStreamSubscription._sendError.sendError (dart:async/stream_impl.dart:360:15)
E/flutter ( 7488): #25     _BufferingStreamSubscription._sendError (dart:async/stream_impl.dart:378:16)
E/flutter ( 7488): #26     _DelayedError.perform (dart:async/stream_impl.dart:602:14)
E/flutter ( 7488): #27     _StreamImplEvents.handleNext (dart:async/stream_impl.dart:706:11)
E/flutter ( 7488): #28     _PendingEvents.schedule.<anonymous closure> (dart:async/stream_impl.dart:663:7)
E/flutter ( 7488): #29     _rootRun (dart:async/zone.dart:1346:47)
E/flutter ( 7488): #30     _CustomZone.run (dart:async/zone.dart:1258:19)
E/flutter ( 7488): #31     _CustomZone.runGuarded (dart:async/zone.dart:1162:7)
E/flutter ( 7488): #32     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1202:23)
E/flutter ( 7488): #33     _rootRun (dart:async/zone.dart:1354:13)
E/flutter ( 7488): #34     _CustomZone.run (dart:async/zone.dart:1258:19)
E/flutter ( 7488): #35     _CustomZone.runGuarded (dart:async/zone.dart:1162:7)
E/flutter ( 7488): #36     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1202:23)
E/flutter ( 7488): #37     _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
E/flutter ( 7488): #38     _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
E/flutter ( 7488): 

我看到了一些关于这些错误的堆栈溢出帖子,但没有一个答案对我有用。对于如何解决它的任何建议,我将不胜感激。如果需要有关我的实施的任何其他信息,请发表评论 - 我会尽快提供。

【问题讨论】:

【参考方案1】:

我得到了同样的错误,但后来我把隐私政策 URL 放在了 facebook 开发者帐户的基本设置中,然后打开了应用程序的直播模式。这对我有用

【讨论】:

以上是关于无法使用 Flutter 和 Firebase 设置 Facebook 身份验证的主要内容,如果未能解决你的问题,请参考以下文章

Flutter 在尝试 Firebase 身份验证时无法捕获 PlatformException

在 Flutter 中使用 Firebase/Google 登录时无法注销并重定向到 LoginPage

Flutter:由于集成了 Firebase 和 Admob,因此无法构建 iOS 应用程序

无法使用 Flutter Mobile 上传到 Firebase 存储

如果应用程序未启动,Flutter Firebase 推送通知无法数据

Firebase 无法在发布版本中初始化,Flutter