Android Google People API error: TokenResponseException: Missing parameter: code
Asked Answered
M

1

3

I've used up my way. I followed the tutorial(part 1 and 2) to use Google People API in my android project. It always hit an error saying parameter code is missing in the signed apk, and stucked at getting GoogleTokenResponse. It works fine in the debug version. What did I do wrong?

And I have done all these:

  • Changed SHA1 to released version.
  • Replace downloaded google-services.json file downloaded from Firebase.
  • Client ID and Client Secret using OAuth Client ID for web
  • Invalidate caches/Restart.
  • Delete and recreate credential.

enter image description here

enter image description here

Google Sign In class:

public void Google_signIn() {

        //migrate to people api
        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                // The serverClientId is an OAuth 2.0 web client ID
                .requestServerAuthCode(Constants.Google_Client_ID)
                .requestEmail()
                .requestScopes(new Scope(Scopes.PLUS_LOGIN),
                        new Scope(PeopleScopes.USERINFO_EMAIL))
                .build();

        if (mGoogleApiClient == null) {

            mGoogleApiClient = new GoogleApiClient.Builder(activity)
                    .enableAutoManage(activity /* FragmentActivity */, this /* OnConnectionFailedListener */)
                    .addOnConnectionFailedListener(this)
                    .addConnectionCallbacks(this)
                    .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
                    .addApi(LocationServices.API)
                    .build();
        }

        Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
        activity.startActivityForResult(signInIntent, GOOGLE_SIGN_IN);
    }

Handler result after signing in successfully:

GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
if (result.isSuccess()) {
            new PeoplesAsync().execute(result);
        }

PeoplesAsync:

class PeoplesAsync extends AsyncTask<GoogleSignInResult, Void, String> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected String doInBackground(GoogleSignInResult... params) {

            GoogleSignInAccount acct = params[0].getSignInAccount();
            JSONObject userInfo = new JSONObject();

            try {

                //basic profile information
                String G_id = acct.getId();
                String G_email = acct.getEmail();
                String G_name = acct.getDisplayName();
                String G_url = acct.getPhotoUrl().toString();//profile img

                userInfo.put(AccountCenter.ACC_ID, G_id);
                userInfo.put(AccountCenter.ACC_NAME, G_name);
                userInfo.put(AccountCenter.ACC_EMAIL, G_email);
                userInfo.put(AccountCenter.ACC_PROFILE_IMAGE, G_url);

                //problem here
                //additional profile information
                com.google.api.services.people.v1.People peopleService = PeopleHelper.setUp(activity, acct.getServerAuthCode());

                com.google.api.services.people.v1.model.Person profile = peopleService.people().get("people/me")
                        .setRequestMaskIncludeField("person.genders,person.urls,person.birthdays").execute();

                if (!profile.isEmpty()) {

                    List<Url> urls = profile.getUrls();
                    List<Gender> genders = profile.getGenders();
                    List<Birthday> birthdays = profile.getBirthdays();

                    String G_link = urls.get(0).getValue();
                    String G_gender = genders.get(0).getValue();
                    Date bday = birthdays.get(0).getDate();
                    String G_birthday = String.format("%02d", bday.getDay()) + "-" + String.format("%02d", bday.getMonth()) + "-" + String.format("%04d", bday.getYear());// check: year will be 0000 if not shown, can be null ?

                    userInfo.put(AccountCenter.ACC_URL, G_link);
                    userInfo.put(AccountCenter.ACC_GENDER, G_gender);
                    userInfo.put(AccountCenter.ACC_BIRTHDAY, G_birthday);
                }

                AccountCenter.setUserInfo(activity, userInfo.toString(), Constants.ACCOUNT_TYPE_GOOGLE);
                memberSocialLogin(activity, userInfo, Constants.ACCOUNT_TYPE_GOOGLE, Constants.PROVIDER_NAME_GOOGLE);

            } catch (IOException ie) {
                ie.printStackTrace();
                return ie.toString();
            } catch (Exception e) {
                e.printStackTrace();
                return e.toString();
            }

            return "1";
        }

        @Override
        protected void onPostExecute(String response) {
            super.onPostExecute(response);

            if (!response.equals("1")) {
                GeneralMethods.hideProgressDialog();

                if (mGoogleSignedInListener != null) {
                    mGoogleSignedInListener.onError(response);
                }
            }
        }
    }

PeopleHelper:

public class PeopleHelper {

    private static final String APPLICATION_NAME = "Grapps";//any name

    public static People setUp(final Context context, String serverAuthCode) {

        String progress = "0%";

        try {

            HttpTransport httpTransport = new NetHttpTransport();
            JacksonFactory jsonFactory = JacksonFactory.getDefaultInstance();

            // Redirect URL for web based applications.
            // Can be empty too.
            String redirectUrl = "";

            progress = "10%";

            //problem here
            // Exchange auth code for access token
            GoogleTokenResponse tokenResponse = new GoogleAuthorizationCodeTokenRequest(
                    httpTransport,
                    jsonFactory,
                    Constants.Google_Client_ID,
                    Constants.Google_Client_Secret,
                    serverAuthCode,
                    redirectUrl).execute();

            progress = "40%";

            // Create a GoogleCredential object using the tokens from GoogleTokenResponse
            GoogleCredential credential = new GoogleCredential.Builder()
                    .setClientSecrets(Constants.Google_Client_ID, Constants.Google_Client_Secret)
                    .setTransport(httpTransport)
                    .setJsonFactory(jsonFactory)
                    .build();

            progress = "60%";

            credential.setFromTokenResponse(tokenResponse);

            progress = "80%";

            // credential can then be used to access Google services
            return new People.Builder(httpTransport, jsonFactory, credential)
                    .setApplicationName(APPLICATION_NAME)
                    .build();

        } catch (IOException e) {

            final String finalProgress = progress + "\n" + e.toString();

            Handler handler = new Handler(context.getMainLooper());
            handler.post(new Runnable() {
                public void run() {
                    GeneralMethods.showAlert(context, "Error setting up People", finalProgress);
                }
            });

            return null;
        }
    }

}
Mediterranean answered 27/10, 2016 at 7:17 Comment(0)
K
1

If there aren’t issues in Google Console and code, try look into Android project setting, set minifyEnabled false in build.gradle might help.

buildTypes {
    release {
//            minifyEnabled true
//            shrinkResources true
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
Kerouac answered 4/11, 2016 at 6:8 Comment(1)
exactly! Don't know why but minifyEnabled true did block me from getting GoogleTokenResponse in signed apk, and my app works perfectly after setting it to false.Mediterranean

© 2022 - 2024 — McMap. All rights reserved.