Google-api-nodejs-client: Uploading app.aab bundle file to play store gives header error.

Created on 7 Jul 2019  路  6Comments  路  Source: googleapis/google-api-nodejs-client

On using API to upload a .aab file generated it gives below error

[ { domain: 'global',
    reason: 'badContent',
    message:
     'Media type \'application/json\' is not supported. Valid media types: [application/octet-stream]'
 } ]

Environment details

  • OS: MAC
  • Node.js version: *latest
  • npm version: *latest
  • googleapis version: "googleapis": "^40.0.1",

Code I use

// our handy library
const { google } = require('googleapis');
const path = require('path');


// this is optional, but helpful
var Promise = require('bluebird');

// just a utility library (handy, if you haven't used it before)
var _ = require('lodash');

// command line parsing
var argv = require('yargs').argv;

// see below in "Finding your secret.json" to find out how to get this
// var key = require('./api-9079692293629174873-456159-6ac82c6d5c83.json');

// I'm using my package.json as my source of truth for my versioning
var version = require('./package.json').version;

// any unique id will do; a timestamp is easiest
var editId = '' + (new Date().getTime());

// editing "scope" allowed for OAuth2
var scopes = [
    'https://www.googleapis.com/auth/androidpublisher'
];

function init() {
    const client = google.auth.getClient({
        keyFile: path.join(__dirname, './api-9079692293629174873-456159-6ac82c6d5c83.json'),
        scopes: 'https://www.googleapis.com/auth/androidpublisher',
    }).then(function(client) {
        // console.log(client);

        var play = google.androidpublisher({
            version: 'v3',
            auth: client,
            params: {
                // default options
                // this is the package name for your initial app you've already set up on the Play Store
                packageName: 'net.test.test'
            }
        });
        // "open" our edit
        startEdit()
            .then(function(data) {
                // console.log(data, "############");
                var aab = require('fs').readFileSync('./android/app/build/outputs/bundle/release/app.aab');
                // console.log(aab);
                // stage the upload (doesn't actually upload anything)
                return upload({
                    edit: data.edit,
                    aab: aab
                });

            }).then(function(data) {

                // log our success!
                console.log('Successful upload:');

            })
            .catch(function(err) {
                console.log(err.errors);
                process.exit(0);
            });

        /**
         *  Sets our authorization token and begins an edit transaction.
         */
        function startEdit() {
            return new Promise(function(resolve, reject) {
                // get the tokens
                play.edits.insert({
                    resource: {
                        id: editId,
                        // this edit will be valid for 10 minutes
                        expiryTimeSeconds: 600
                    }
                }, function(err, edit) {
                    if (err || !edit) {
                        reject(err);
                    }

                    resolve({
                        edit: edit
                    });
                });
            });
        }

        /**
         *  Stages an upload of the APK (but doesn't actually upload anything)
         */
        function upload(data) {
            var edit = data.edit.data;
            var aab = data.aab;
            // console.log(play.edits);
            return new Promise(function(resolve, reject) {
                play.edits.bundles.upload({
                    editId: edit.id,
                    packageName: 'net.test.test',
                    media: {
                        "mimeType": 'application/octet-stream',
                        body: aab
                    }
                }, function(err, res) {
                    var test = Object.keys(err);
                    console.log(res);
                    if (err || !res) {
                        reject(err);
                    }

                    // pass any data we care about to the next function call
                    resolve(_.omit(_.extend(data, {
                        uploadResults: res
                    }), 'aab'));
                });
            });
        }
    });
}
init();

question

Most helpful comment

you can try out changing var aab = require('fs').readFileSync('./android/app/build/outputs/bundle/release/app.aab');
to var aab = require('fs').createReadStream('./android/app/build/outputs/bundle/release/app.aab');

All 6 comments

you can try out changing var aab = require('fs').readFileSync('./android/app/build/outputs/bundle/release/app.aab');
to var aab = require('fs').createReadStream('./android/app/build/outputs/bundle/release/app.aab');

Confirm that using createReadStream allows to upload the App Bundle

@stripathix did @nasmuris' recommendation do the trick for you?

@bcoe Yes, all I had to do was change readFileSync into createReadStream
I even could use await on upload without the Promise wrappers.

I believe the above code is based partly on this article:
USING NODE.JS TO UPLOAD YOUR APP TO GOOGLE PLAY

And here is also the source code from the author

Due to some reason I am getting. Not sure what's an issue.
media failed, reason: socket hang up

I get the same error : media failed: socket hang up. @stripathix, did you find a way to make it work ?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

oliverjessner picture oliverjessner  路  3Comments

ovaris picture ovaris  路  3Comments

raapperez picture raapperez  路  3Comments

nanu-c picture nanu-c  路  3Comments

streamnsight picture streamnsight  路  4Comments