2016-03-27 90 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