Google Play Games, Firebase and the new Google Sign-in

自闭症网瘾萝莉.ら 提交于 2020-01-19 14:20:49

问题


My game is using Google Play Games and Firebase (for Rankings System, because unfortunately one cannot reduce the score in Google Leaderboards).

In the past I used the deprecated way to sign-in to Firebase via Plus.AccountApi.getAccountName and friends...

So I tried to convert to the new Google Sign-in, but apparently it cannot be used in conjuction with Google Play Games:

Auth.GOOGLE_SIGN_IN_API cannot be used with Games.API

My whole goal was/is to get rid of Google+ dependency (as Google Play Games doesn't require it anymore) and the GET_ACCOUNTS permission.

How can I sign in to Firebase without Google+ and GET_ACCOUNTS - and without the new Google Sign-in? Can I? Perhaps creating two separate GoogleApiClients would be a solution?


回答1:


Well, I simply ended up creating two separate GoogleApiClients: one for Google Play Games, and another for Firebase (using the new Google sign-in). I see no problems with this approach, and I got rid of the Google+ dependency & GET_ACCOUNTS permission.




回答2:


To use Google Play Games Api with Firebase follow these steps:

***Note: getGamesServerAuthCode is the recommended way from Google; although it's depreciated. They may have forgot to remove the deprecation annotation when releasing to general public.

Step 1: When you have successfully signed in; get the authorization code. You may use onSignInSucceeded() for example. Just make sure the API Client is connected.

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);
                }
            }
        });

Step 2: Exchange that authorization code for a token.

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();
}

Step 3: Use the authorization code to sign-in with 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());
                        }
                    }
                });
    }


来源:https://stackoverflow.com/questions/36247959/google-play-games-firebase-and-the-new-google-sign-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!