2016-03-27 56 views
5

我的游戏正在使用Google Play游戏和Firebase(对于排名系统,因为不幸的是无法降低Google排行榜的分数)。Google Play游戏,Firebase和新的Google登录

在过去我曾经通过Plus.AccountApi.getAccountName和朋友登录到火力地堡的弃用方式...

于是,我就转换为新的谷歌帐户登录,但显然它不能一起选择使用与谷歌玩游戏:

Auth.GOOGLE_SIGN_IN_API cannot be used with Games.API 

我的整个目标是/是摆脱Google+的依赖(如谷歌玩游戏并不需要它了)和GET_ACCOUNTS许可。

如何在没有Google+和GET_ACCOUNTS的情况下登录Fi​​rebase - 并且无需新的Google登录?我可以吗?也许创建两个独立的GoogleApiClient会是一个解决方案?

+0

没有看到最小的代码来重现您的问题,它不可能说出为什么它不工作。请参阅[MCVE](http://stackoverflow.com/help/mcve)。 –

回答

2

嗯,我最终创建了两个独立的GoogleApiClient:一个用于Google Play游戏,另一个用于Firebase(使用新的Google登录)。我发现这种方法没有问题,并且我摆脱了Google+依赖性& GET_ACCOUNTS权限。

+0

我正面临类似的问题。我想从您的使用案例中了解更多细节。 如何对两个connect()调用进行排序? (我假设你必须拨打两个独立的连接电话) – dlmt

+0

使用2个独立的API客户端,如果用户在其设备上拥有多个帐户,如何避免选择其他Google帐户或玩游戏帐户的问题?我可以很容易地看到两个不匹配的情况。 – Moritz

1

要使用谷歌玩游戏API和火力地堡请按照下列步骤操作:

***注:getGamesServerAuthCode是从谷歌推荐的方式;尽管这是贬值。在向公众发布时,他们可能忘记删除弃用注释。

第1步: 成功登录后;获取授权码。例如,您可以使用onSignInSucceeded()。只要确保API客户端已连接。

Games.getGamesServerAuthCode(gameHelper.getApiClient(), [web_client_id]).setResultCallback(new ResultCallback<Games.GetServerAuthCodeResult>() { 
      @Override 
      public void onResult(@NonNull Games.GetServerAuthCodeResult result) { 
       if (result.getStatus().isSuccess()) { 
        String authCode = result.getCode(); 
        exchangeAuthCodeForToken(authCode); 
       } 
      } 
     }); 

步骤2:交换令牌的授权码。

class AuthToken { 
    String access_token; 
    String token_type; 
    int expires_in; 
    String id_token; 
} 

void exchangeAuthCodeForToken(final String authCode) { 
    AsyncTask<Void, Void, AuthToken> task = new AsyncTask<Void, Void, AuthToken>() { 
     @Override 
     protected AuthToken doInBackground(Void... voids) { 
      try { 
       URL url = new URL("https://www.googleapis.com/oauth2/v4/token"); 
       Map<String, Object> params = new LinkedHashMap<>(); 
       params.put("code", authCode); 
       params.put("client_id", "[web_client_id]"); 
       params.put("client_secret", "[secret]"); 
       params.put("redirect_uri", "[redirect_uri]"); 
       params.put("grant_type", "authorization_code"); 

       StringBuilder postData = new StringBuilder(); 
       for (Map.Entry<String, Object> param : params.entrySet()) { 
        if (postData.length() != 0) postData.append('&'); 
        postData.append(URLEncoder.encode(param.getKey(), "UTF-8")); 
        postData.append('='); 
        postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8")); 
       } 
       byte[] postDataBytes = postData.toString().getBytes("UTF-8"); 

       HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
       conn.setRequestMethod("POST"); 
       conn.setRequestProperty("Host", "www.googleapis.com"); 
       conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 
       conn.setDoOutput(true); 
       conn.getOutputStream().write(postDataBytes); 

       int responseCode = conn.getResponseCode(); 
       if (responseCode == HttpsURLConnection.HTTP_OK) { 
        Reader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8")); 

        // Build the string 
        StringBuilder sb = new StringBuilder(); 
        for (int c; (c = in.read()) >= 0;) { 
         sb.append((char) c); 
        } 

        // Convert JSON to a Java Object 
        GsonBuilder builder = new GsonBuilder(); 
        Gson gson = builder.create(); 
        AuthToken token = gson.fromJson(sb.toString(), AuthToken.class); 

        // Disconnect 
        conn.disconnect(); 

        return token; 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      return null; 
     } 

     @Override 
     protected void onPostExecute(AuthToken token) { 
      // Authorize Firebase with Games API 
      firebaseAuthWithGamesApi(token.id_token); 
     } 

    }.execute(); 
} 

步骤3:使用授权码通过Firebase登录。

private void firebaseAuthWithGamesApi(String authToken) { 
     AuthCredential credential = GoogleAuthProvider.getCredential(authToken, null); 
     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()); 
         } 
        } 
       }); 
    } 
+0

它可以是一个解决方案,但'Games.getGamesServerAuthCode'已被弃用,并且下一个网络请求返回没有'id_token'的令牌信息,需要获取我们需要登录到firebase的'AuthCredential' – mohax

+0

我从某篇文章中听说它是标记为折旧并且他们忘记删除它。但不知道。我确定他们正在进行更换。但是,我还没有看到它。 –

+0

怎么样缺少'id_token'?我试着从这里得到一些答案,但不能在响应中获得这个字段(Ony'acces_token'返回,当我尝试将它传递给GoogleAuthProvider.getCredential时,它失败并显示它无法识别'id_token'这里的消息 – mohax