Android FireBase - 连接到游戏服务排行榜

Posted

技术标签:

【中文标题】Android FireBase - 连接到游戏服务排行榜【英文标题】:Android FireBase - Connect to Game Service Leaderboard 【发布时间】:2017-07-11 02:55:38 【问题描述】:

我使用 firebase 进行了登录活动以连接谷歌。用户可以毫无问题地登录现在我想在另一个活动中显示排行榜但是,当我检查用户是否已登录并尝试显示排行榜时出现错误:

E/UncaughtException: java.lang.IllegalStateException: GoogleApiClient 必须连接。

如何使用 Firebase 连接 GoogleApiClient?我尝试过使用mGoogleApiClient.connect(GoogleApiClient.SIGN_IN_MODE_OPTIONAL);,但这也不起作用。

这是我的代码:

      protected void onCreate(Bundle savedInstanceState) 
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_achievements);


                // Configure Google Sign In
                GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                        .requestIdToken(getString(R.string.default_web_client_id))
                        .requestEmail()
                        .build();

                mGoogleApiClient = new GoogleApiClient.Builder(this)
                        .enableAutoManage(this, new GoogleApiClient.OnConnectionFailedListener() 
                            @Override
                            public void onConnectionFailed(@NonNull ConnectionResult connectionResult) 
                                // connection failed, should be handled
                            
                        )
                        .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
                        .build();

                mAuth = FirebaseAuth.getInstance();

                mAuthListener = new FirebaseAuth.AuthStateListener() 
                    @Override
                    public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) 
                        FirebaseUser user = firebaseAuth.getCurrentUser();
                        if (user != null) 
                            // User is signed in
                            Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());

     ////// is crashing googleapiclient not connected

startActivityForResult(Games.Leaderboards.getLeaderboardIntent(mGoogleApiClient,
                                    getString(R.string.leaderboard_la_classifica)), REQUEST_LEADERBOARD); 

                         else 
                            // User is signed out
                        
                        // ...
                    
                ;

            

【问题讨论】:

【参考方案1】:

请参阅https://firebase.google.com/docs/auth/android/google-signin 了解更多详情。

在构建客户端时,需要使用 GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN。

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
       setContentView(R.layout.fragment_firebase_games_signin);

     String webclientId = getString(R.string.web_client_id);

    GoogleSignInOptions options =
            new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
                    .requestServerAuthCode(webclientId)
                    .requestEmail()
                    .requestIdToken()
                    .build();

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(Games.API).addScope(Games.SCOPE_GAMES)
            .addApi(Auth.GOOGLE_SIGN_IN_API, options)
            .addConnectionCallbacks(this)
            .build();


然后要启动显式登录,请启动 signIn Intent:

private void signIn() 
    Intent signInIntent =
         Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
    startActivityForResult(signInIntent, RC_SIGN_IN);

您还应该使用自动管理的客户端,或者直接在onStart() 中调用mGoogleApiClient.connect(GoogleApiClient.SIGN_IN_MODE_OPTIONAL); 并在onStop() 中断开连接。

在onActivityResult中,处理显式登录intent的结果:

@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) 
        GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
        if (result.isSuccess()) 
            // Google Sign In was successful, authenticate with Firebase
            GoogleSignInAccount acct = result.getSignInAccount();

            completeFirebaseAuth(acct);

            // At this point, the Games API can be called.

         else 
            // Google Sign In failed, update UI appropriately
            // ...
        
    

完成 Firebase 身份验证:

private void completeFirebaseAuth(GoogleSignInAccount  acct) 
    AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
    FirebaseAuth mAuth = FirebaseAuth.getInstance();
    mAuth.signInWithCredential(credential)
            .addOnCompleteListener(this, new
                    OnCompleteListener<AuthResult>() 
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) 
                    Log.d(TAG, "signInWithCredential:onComplete:" + task.isSuccessful());

                    // If sign in fails, display a message to the user. If sign in succeeds
                    // the auth state listener will be notified and logic to handle the
                    // signed in user can be handled in the listener.
                    if (!task.isSuccessful()) 
                        Log.w(TAG, "signInWithCredential", task.getException());
                    
                    // ...
                
            );

您需要处理的另一种情况是静默登录,在恢复应用时发生:

@Override
public void onConnected(@Nullable Bundle bundle) 

    // Handle the silent sign-in case.

    if (mGoogleApiClient.hasConnectedApi(Games.API)) 
        Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient).setResultCallback(
                new ResultCallback<GoogleSignInResult>() 
                    @Override
                    public void onResult(
                            @NonNull GoogleSignInResult googleSignInResult) 
                        if (googleSignInResult.isSuccess()) 
                            completePlayGamesAuth(
                                    googleSignInResult.getSignInAccount());
                         else 
                            Log.e(TAG, "Error with silentSignIn: " +
                                    googleSignInResult.getStatus());
                        
                    
                
        );
    

【讨论】:

以上是关于Android FireBase - 连接到游戏服务排行榜的主要内容,如果未能解决你的问题,请参考以下文章

无法让 Android 应用连接到 Firebase

获取用于从 Android 设备连接到 Firebase 的 IP 地址 [重复]

无法将 Firebase 连接到 Android 应用 |此应用无权使用 Firebase 身份验证

最近的 Android Studio 无法连接到 Firebase?

只有 Android 应用程序模块可以连接到 Firebase 在线项目

如何从 Android 应用程序连接到多个 Firebase 数据库