Skip to content

Instantly share code, notes, and snippets.

@ianlintner-wf
Last active February 19, 2019 10:10
Show Gist options
  • Save ianlintner-wf/9b042900cd70b518b506fb989d7085c0 to your computer and use it in GitHub Desktop.
Save ianlintner-wf/9b042900cd70b518b506fb989d7085c0 to your computer and use it in GitHub Desktop.
This is to fix version issues between multiple google services plugins in Ionic & cordova builds. Cordova before_prepare hook.
#!/usr/bin/env node
// Define hook in your config <hook src="scripts/cordova-google-services-version-gradle-fix.js" type="before_prepare" />
var sourceDir = '';
var platformDir = 'platforms/android';
var fs = require('fs');
var path = require('path');
var readline = require("readline");
module.exports = function(ctx) {
console.log('-----------------------------');
console.log('Gradle Fix');
if (ctx.opts.platforms.indexOf('android') < 0) {
return;
}
var Q = ctx.requireCordovaModule('q');
var deferred = Q.defer();
var platformRoot = path.join(ctx.opts.projectRoot, 'platforms/android');
var gradle = path.join(platformRoot, 'project.properties');
console.log(gradle);
fs.readFile(gradle, 'utf8', function (err,data) {
if (err) {
console.log(err);
deferred.reject(err);
}
var result = data.replace(/play-services-auth:.*/g, 'play-services-auth:9.8.0')
.replace(/play-services-identity:.*/g, 'play-services-identity:9.8.0');
fs.writeFile(gradle, result, 'utf8', function (err) {
if (err) {
console.log('error');
console.log('-----------------------------');
deferred.reject(err);
}
console.log('complete');
console.log('-----------------------------');
deferred.resolve();
});
});
return deferred.promise;
};
@ianlintner-wf
Copy link
Author

Updates bad build versions provided by plugins and forces them to use one version.

Ionic Cordova Gradle Google Services Version issue

e.g. plugin defines framework com.google.android.gms:play-services-auth:+

@ianlintner-wf
Copy link
Author

Also this is not great code. It is messy and matches too much, but it gets the job done till libs/plugins get patched for me.

@morariu
Copy link

morariu commented Jun 6, 2017

Thanks but this didn't work for me, getting the same error:

A problem occurred evaluating root project 'android'.
> Failed to apply plugin [id 'com.google.gms.google-services']
   > For input string: "+"

@probil
Copy link

probil commented Sep 30, 2017

I got the same issue, so I've added play-services-fitness and it works for me know!
My updated hook-file (with style fixes):

#!/usr/bin/env node

// Define hook in your config:
// <platform name="android">
//    <hook src="scripts/cordova-google-services-version-gradle-fix.js" type="before_prepare" />
// </platform>

const fs = require('fs');
const path = require('path');

module.exports = (ctx) => {
  console.log('-----------------------------');
  console.log('> Gradle - fix `play-services` versions');

  const Q = ctx.requireCordovaModule('q');
  const deferred = Q.defer();

  const gradle = path.join(ctx.opts.projectRoot, 'platforms', 'android', 'project.properties');
  console.log(gradle);
  fs.readFile(gradle, 'utf8', (err, data) => {
    if (err) {
      console.log(err);
      return deferred.reject(err);
    }
    const result = data
      .replace(/play-services-auth:.*/g, 'play-services-auth:11.0.4')
      .replace(/play-services-identity:.*/g, 'play-services-identity:11.0.4')
      .replace(/play-services-fitness:.*/g, 'play-services-fitness:11.0.4');

    return fs.writeFile(gradle, result, 'utf8', (err) => {
      if (err) {
        console.log('error');
        console.log('-----------------------------');
        deferred.reject(err);
      }
      console.log('completed');
      console.log('-----------------------------');
      deferred.resolve();
    });
  });

  return deferred.promise;
};

List of all the libraries here: https://developers.google.com/android/guides/setup

@codinronan
Copy link

codinronan commented Dec 13, 2017

My own version! Only difference here and the one above, is that I have made the libraries a list, so that you don't have to keep adding individual replace statements.

#!/usr/bin/env node

// Define hook in your config:
// <platform name="android">
//    <hook src="scripts/gms-gradle-fix.js" type="before_prepare" />
// </platform>

const fs = require('fs');
const path = require('path');

const FCM_VERSION = '11.6.0';

// You can include more of each string if there are naming conflicts,
// but for the GMS libraries each should be unique enough.
// The full list of libraries is here:
// https://developers.google.com/android/guides/setup
const LIBRARIES = [
  'play-services-maps',
  'play-services-location',
  'play-services-auth',
  'play-services-identity',
  'firebase-messaging',
];

const createRegex = (item) => new RegExp(`${item}:.*`, 'ig');
const createReplace = (item) => `${item}:${FCM_VERSION}`;

module.exports = (ctx) => {
  console.log('-----------------------------');
  console.log('> Gradle - fix `play-services` versions');

  const Q = ctx.requireCordovaModule('q');
  const deferred = Q.defer();

  const gradle = path.join(ctx.opts.projectRoot, 'platforms', 'android', 'project.properties');
  console.log(gradle);
  fs.readFile(gradle, 'utf8', (err, data) => {
    if (err) {
      console.log(err);
      return deferred.reject(err);
    }

    let result = data;
    LIBRARIES.forEach((lib) => {
      result = result.replace(createRegex(lib), createReplace(lib));
    })

    return fs.writeFile(gradle, result, 'utf8', (err) => {
      if (err) {
        console.log('error');
        console.log('-----------------------------');
        deferred.reject(err);
      }
      console.log('completed');
      console.log('-----------------------------');
      deferred.resolve();
    });
  });

  return deferred.promise;
};

@kingkarki
Copy link

none of these work any more

@kfrijters
Copy link

Thank you, worked like a charm! just had to change FCM_VERSION to a more recent version

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment