Flutter - Firebase使用Facebook进行身份验证无法将用户信息保存到数据库中。

3
我想让用户使用Facebook登录,并检查该用户是否已存在于数据库中。 如果用户(uid)已存在,则应正常登录,但如果用户不在数据库中,则要将用户发送到创建帐户页面。 这是我的代码,但它没有起作用。 它允许用户进行登录,但无法从用户资料中提取任何数据,我该怎么办?
  //Login with Facebook
  void signInUsingFacebook() async {
    final FacebookLogin facebookLogin = FacebookLogin();
    final FacebookLoginResult facebookLoginResult =
        await facebookLogin.logIn(['email']);
    switch (facebookLoginResult.status) {
      case FacebookLoginStatus.loggedIn:
        // TODO: Handle this case.
        FirebaseAuth.instance.signInWithCredential(
          FacebookAuthProvider.getCredential(
              accessToken: facebookLoginResult.accessToken.token),
        );
        FirebaseUser currentUser = await FirebaseAuth.instance.currentUser();
        if (currentUser != null) {
          print('user is logged in');
          await _pushNotificationService.initialise();

          final DocumentSnapshot doc =
              await usersRef.document(currentUser.uid).get();
          //Storing the user data in the firestore database

          if (!doc.exists) {
            final userDetails = await Navigator.push(context,
                MaterialPageRoute(builder: (context) => CreateAccount()));
            _db.collection("users").document(currentUser.uid).setData({
              "username": userDetails[1],
              "displayName": userDetails[2],
              "email": currentUser.email,
              "photUrl": userDetails[0],
              "gender": userDetails[3],
              "timestamp": timestamp,
              "signin_method": currentUser.providerId,
              "location": userDetails[4],
              "uid": currentUser.uid,
              "points": 0,
              "bio": userDetails[5],
            });
          }
        }
        break;
      case FacebookLoginStatus.cancelledByUser:
        // TODO: Handle this case.
        print('cancelled by user');
        break;
      case FacebookLoginStatus.error:
        // TODO: Handle this case.
        print('login error');
        break;
    }

1个回答

3

我差点忘了这个查询。最终我解决了如何使它正确运行,所以我在下面发布代码供任何想使用它的人使用。希望能有所帮助!

  //Login with Facebook
  void signInUsingFacebook() async {
    final FacebookLogin facebookLogin = FacebookLogin();
    final FacebookLoginResult facebookLoginResult =
        await facebookLogin.logIn(['email']);
    switch (facebookLoginResult.status) {
      case FacebookLoginStatus.loggedIn:
        setState(() {
          showSpinner = true;
        });
        // TODO: Handle this case.
        FirebaseAuth.instance
            .signInWithCredential(
          FacebookAuthProvider.getCredential(
              accessToken: facebookLoginResult.accessToken.token),
        )
            .then((user) async {
          await _pushNotificationService.initialise();
          final graphResponse = await http.get(
              'https://graph.facebook.com/v2.12/me?fields=name,picture,email&access_token=${facebookLoginResult.accessToken.token}');
          final profile = JSON.jsonDecode(graphResponse.body);

          final DocumentSnapshot doc =
              await usersRef.document(user.user.uid).get();
          //Storing the user data in the firestore database

          if (!doc.exists) {
            final userDetails = await Navigator.push(
                context, MaterialPageRoute(builder: (ctx) => CreateAccount()));

            _db.collection("users").document(user.user.uid).setData({
              "username": userDetails[0],
              "displayName": userDetails[1],
              "email": profile['email'],
              "photUrl": "N/A",
              "gender": userDetails[2],
              "timestamp": timestamp,
              "signin_method": 'Facebook',
              "location": userDetails[4],
              "uid": user.user.uid,
              "points": 0,
              "bio": userDetails[3],
            });
          }
          setState(() {
            showSpinner = false;
          });
          Navigator.pushReplacement(
            context,
            MaterialPageRoute(
              builder: (context) => UserProfile(),
            ),
          );
        });

        break;
      case FacebookLoginStatus.cancelledByUser:
        // TODO: Handle this case.
        setState(() {
          showSpinner = false;
        });

        break;
      case FacebookLoginStatus.error:
        // TODO: Handle this case.
        setState(() {
          showSpinner = false;
        });

        break;
    }
  }

解释: 问题代码和答案代码的主要区别在于以下部分:

// TODO: Handle this case.
        FirebaseAuth.instance
            .signInWithCredential(
          FacebookAuthProvider.getCredential(
              accessToken: facebookLoginResult.accessToken.token),
        ).then((user))async{}

在当前版本的flutter_facebook_login包中,先获取当前用户对象,然后尝试获取该当前用户的访问令牌是行不通的。

您必须使用FirebaseAuth.instance.signInWithCredential()方法,并使用FacebooAuthProvider().getCredential(accessToken:)。这将让Firebase使用凭据进行登录并返回当前用户对象。现在,您可以使用当前用户对象将详细信息存储到firestore数据库中。

注意:Facebook以JSON格式返回用户详细信息。因此,在使用之前必须解码JSON数据。下面是解码JSON数据的代码:

final graphResponse = await http.get(
              'https://graph.facebook.com/v2.12/me?fields=name,picture,email&access_token=${facebookLoginResult.accessToken.token}');
          final profile = JSON.jsonDecode(graphResponse.body);

希望这有所帮助!干杯!


虽然代码可能解决了这个问题,但是如果您能够包含一个解释(//meta.stackexchange.com/q/114762)以说明如何以及为什么解决了这个问题,那么就会大大有助于提高您的帖子质量,并且可能会得到更多的赞。请记住,您正在回答未来的读者的问题,而不仅仅是问问题的人。请编辑您的回答以添加解释并指出哪些限制和假设适用。 - rizerphe
谢谢你指出这一点。我一定会添加这段代码背后的解释。 - hasib_ullah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接