13

We are preparing a firebase trigger to handle android's real-time developer notifications, and we have to use Google Play Developer API to understand the details for user subscriptions. Thus we linked firebase service account in Google Play Console and also granted necessary access.

We used google's nodejs library for googleapis (github link) and wrote a piece of code like this:

return google.auth.getClient({
  keyFile: path.join(__dirname, './service-account.json'),
  scope: 'https://www.googleapis.com/auth/androidpublisher'
}) .then((client) => {
  const androidpublisher = google.androidpublisher({
    version: 'v3',
    auth: client
  });
  const params = {
    packageName: ANDROID_PACKAGE_NAME,
    subscriptionId: ANDROID_SUBSCRIPTIONID,
    token: token
  };
  return androidpublisher.purchases.subscriptions.get(params)
  .then(res => {
    console.log(`The response is ${res.data}`);
    return null;
  })
  .catch(error => {
    console.error(error);
  });
});

But it returns us an error states: 'Invalid Credentials', which I am a bit lost for this. I have tested using curl that API with the authorization token and it shows 401 error response as well.

I am not sure whether my flow above is correct, can anyone provide me any suggestions?

auspicious99
  • 3,902
  • 1
  • 44
  • 58
Yuyun Zhou
  • 131
  • 4
  • Invalid Credentials normally means that the client id you are using doesnt match the key you are using. try downloading your serviceaccount.json file again. Are you sure that service accounts work with that api? – Linda Lawton - DaImTo Aug 23 '18 at 11:04
  • @DaImTo This was the first thing came to our mind last time. We have tried to download again and even created a different service account and tested, but it seems not solving the issue. – Yuyun Zhou Aug 24 '18 at 01:46
  • Are you sure that the code you are using is intended for a service account and not for Oauth2? The client types are different as is the code to use them. – Linda Lawton - DaImTo Aug 24 '18 at 06:39
  • Yes, it is for a service account. So, this code is on firebase, as a cloud function with pubsub trigger, where the pubsub notification has been successfully received when there was an in app purchase, and then we got the package name, subscription ID and token, tried to authenticate to query google play for more info, and that is where it fails. – auspicious99 Sep 20 '18 at 10:16

1 Answers1

7

With JWT from google-auth-library. Google sample

const googleapis = require('googleapis');
const { JWT } = require('google-auth-library');
const serviceAccount = require('./serviceAccountKey.json');

const getAuthorizedClient = () => new JWT({
    email: serviceAccount.client_email,
    key: serviceAccount.private_key,
    scopes: ['https://www.googleapis.com/auth/androidpublisher']
});

const getAndroidpublisher = () => googleapis.google.androidpublisher({
    version: 'v3',
    auth: getAuthorizedClient()
});

const requestProductValidation = data => new Promise((resolve, reject) => {
    getAndroidpublisher().purchases["products"].get(data, (err, response) => {
        if (err) {
            console.log(`The API returned an error: ${err}`);
            resolve({status: "Error"});
        } else {
            const isValid = response && response.data && response.data.purchaseState === 0;
            resolve({status: isValid ? "OK" : "Error"});
        }
    });
});

exports.purchaseValidationAndroid = functions.https.onCall((data, context) => {
    return requestProductValidation(data);
});

data contains productId, token and packageName

evgen shein
  • 81
  • 1
  • 2
  • 7