GoogleCredentials: getTokenValue() works on emulator, but not on an actual device

Viewed 26

For use on a mobile app, I'm authenticating for a Firebase realtime db. The code for reading the private key and generating an access token works fine on the Android emulator, but generates an error on an actual phone.

Here's the code:

private String getToken () {
    try {
        InputStream serviceAccount      = getApplicationContext().getAssets().open("asset.json");
        GoogleCredentials googleCred    = GoogleCredentials
                .fromStream (serviceAccount)
                .createScoped (Arrays.asList(
                    "https://www.googleapis.com/auth/firebase.database",
                    "https://www.googleapis.com/auth/userinfo.email"
                ));

        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);

        try {
            return googleCred.refreshAccessToken().getTokenValue();
        }
        catch (Exception e) {
            Log.d ("getToken", "Auth 2 Error: " + e);
            return "";
        }
    }

    catch (Exception e) {
        Log.d ("getToken", "Auth 1 Error: " + e);
        return "";
    }
}

When this code is run on the phone, the error generated is:

Auth 2 Error:
I5.m: Error getting access token for service account: 400 Bad Request
POST https://oauth2.googleapis.com/token
{
    "error": "invalid_grant",
    "error_description": "Invalid grant: account not found"
}
iss:  xxxredactedxxx@appspot.gserviceaccount.com

The private key asset is being read correctly on both emulator and phone, so I suspect the problem is not in the code, but something in my Firebase and/or Google Cloud setup. What "account" is needed when the app is run on a phone but not in the emulator? And where would I set up that account?

Edit: In the Google Cloud Service Accounts page, I've added the iss account (in the error message) to "Principals with access to this Service Account" table:

Principal: xxxredactedxxx@appspot.gserviceaccount.com   
Name:      App Engine default service account   
Role:      Editor
           Service Account Token Creator

(To be clear, I'm not using logins or other userid/password-style authentication; the app should connect internally to its db in Firebase in a read-only mode, based on the private key).

0 Answers
Related