【问题标题】:Firebase Authentication with Google Play Games使用 Google Play 游戏进行 Firebase 身份验证
【发布时间】:2019-10-30 06:44:25
【问题描述】:

我正在为安卓创建游戏。每个用户都需要经过身份验证。

目前,当新用户启动游戏时,它会从我的服务器请求一个识别码,并将其存储到 SharedPreferences。下次用户启动游戏时,它会使用此存储的识别码进行身份验证。问题是,当用户清除这个应用的数据时,他无法找回他的ID,所以他永远失去了他的进步。

有没有办法使用 Firebase Play 游戏身份验证方法生成唯一且对于一个玩家始终相同的识别码?

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
                .requestServerAuthCode("MyCID")
                .build();

        mAuth = FirebaseAuth.getInstance();
        super.onCreate(savedInstanceState);
        final FirebaseAuth auth = FirebaseAuth.getInstance();
        AuthCredential credential = PlayGamesAuthProvider.getCredential("MyCID");
        auth.signInWithCredential(credential)
                .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                    public void onComplete(@NonNull Task<AuthResult> task) {
                        if (task.isSuccessful()) {
                            currentUser = auth.getCurrentUser();
                        } else {
                            Toast.makeText(MainActivity.this, "Authentication failed.",
                                    Toast.LENGTH_SHORT).show();
                        }
                    }
                });
        if (currentUser == null) {
            cu = "NO UID";
        } else {
            cu = currentUser.getUid();
        }

我尝试了这段代码(MyCID 在哪里:我使用了下图中的 CID),但没有显示 Google Play 游戏弹出窗口,我得到 Authentication Failed toast 并且 cu 设置为“NO UID”。

有人可以解释一下这是如何工作的吗?


编辑

感谢@crysxd,我的应用现在显示绿色的 google play 游戏弹出窗口。但是,正如我在其他使用谷歌游戏登录的游戏中看到的那样,我收到了一个错误,提示“com.google.android.gms.common.api.ApiException: 4:”,而不是预期的“选择一个帐户”弹出窗口。

我需要运行一个函数来显示这个对话框吗?是我遗漏了什么,还是我在 Google Play 控制台中错误地配置了游戏?

我当前的代码:link

【问题讨论】:

    标签: java android firebase firebase-authentication google-play-games


    【解决方案1】:

    您在这里跳过了一个重要步骤。 Firebase 文档通常非常好,但对 Play 登录的描述很差。

    第一步做对了:您需要设置GoogleSignInOptions,但您错过了将它们传递给GoogleSignInClient

    • onCreate中创建一个客户端:

      private static final int RC_SIGN_IN = 543;
      private GoogleSignInClient mGoogleSignInClient;
      
      public void onCreate(Bundle savedInstancestate) {
          super.onCreate(savedInstancestate)
      
          // ...
      
          GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
                  .requestServerAuthCode("MyCID")
                  .build();
      
          mGoogleSignInClient= GoogleSignIn.getClient(this, gso)
      }
      
    • 当点击登录按钮或您想开始登录时调用此方法。这将导致显示登录对话框。

      private void signIn() {
          Intent signInIntent = mGoogleSignInClient.getSignInIntent();
          startActivityForResult(signInIntent, RC_SIGN_IN);
      }
      
    • 获取登录响应并处理它

      @Override
      public void onActivityResult(int requestCode, int resultCode, Intent data) {
          super.onActivityResult(requestCode, resultCode, data);
      
          // Result returned from launching the Intent from 
          GoogleSignInApi.getSignInIntent(...);
          if (requestCode == RC_SIGN_IN) {
              Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
              try {
                  // Google Sign In was successful, authenticate with Firebase
                  GoogleSignInAccount account = task.getResult(ApiException.class);
                  firebaseAuthWithGoogle(account);
              } catch (ApiException e) {
                  // Google Sign In failed, update UI appropriately
                  Log.w(TAG, "Google sign in failed", e);
              }
          }
      }
      
    • 最后,您的代码开始发挥作用。现在我们有了调用PlayGamesAuthProvider.getCredential(...) 所需的GoogleSignInAccount。您在这里传递了您的客户 ID,但这是错误的。它是这样工作的:您将您的客户 ID 提供给 Google 只是为了告诉他们您是谁(或哪个应用程序)。他们会让用户登录并给你一个特殊的令牌(“id 令牌”),然后 Firebase 可以使用它从 Google Play 游戏中获取有关用户的信息。这就是您需要在此处提供给 Firebase 的令牌:

      private void firebaseAuthWithGoogle(GoogleSignInAccount acct) {
          Log.d(TAG, "firebaseAuthWithGoogle:" + acct.getId());
      
          AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
          mAuth.signInWithCredential(credential)
              .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                  @Override
                  public void onComplete(@NonNull Task<AuthResult> task) {
                      if (task.isSuccessful()) {
                          // Sign in success, update UI with the signed-in user's information
                          Log.d(TAG, "signInWithCredential:success");
                          FirebaseUser user = mAuth.getCurrentUser();
                          updateUI(user);
                      } else {
                          // If sign in fails, display a message to the user.
                          Log.w(TAG, "signInWithCredential:failure", task.getException());
                          Snackbar.make(findViewById(R.id.main_layout), "Authentication Failed.", Snackbar.LENGTH_SHORT).show();
                          updateUI(null);
                      }
      
                      // ...
                  }
              });
      }
      

    希望对您有所帮助!您可以在文档 herehere 中找到引用的完整代码(这些是他们在文档中显示 sn-ps 的文件)。

    【讨论】:

    • 好吧,它有效,我得到了 google play games 弹出窗口,但我在 onActivityResult 方法中遇到错误,就在这里GoogleSignInAccount account = task.getResult(ApiException.class);ApiException e 说“com.google.android.gms.common.api.ApiException: 4:”我找不到这个错误代码 4 是什么意思。
    • Google 只为您提供定义为 here 的错误代码。 4 表示需要登录,这没有太大意义。看看here
    • 好像少了点什么。我找到了一个带有 Google Games Auth 的应用程序,并且有一个弹出窗口显示“选择帐户以继续”。我没有这个弹出窗口,它只显示“需要登录”错误。
    • 是的,当您启动意图时应该会弹出对话框。对话框的结果被传递给 onActivityResult。如第一条评论中所述,我认为这已经对您有用。您还看到什么其他对话框?您是否在设备上使用 Google 帐户登录?你能和整个班级一起做一个 GitHub 要点吗?
    猜你喜欢
    • 2018-02-09
    • 2016-05-11
    • 2019-07-29
    • 2020-07-15
    • 2017-02-10
    • 1970-01-01
    • 2017-03-11
    • 2018-10-19
    • 2021-02-08
    相关资源
    最近更新 更多