Cordova 6 Bug with Plugin Variables in Gradle

August 10th 2018 Cordova Android

Cordova plugins can use variables for project specific values which must be entered when installing them. For example, Google Maps plugin uses them for setting the API keys. When these variables are used in Gradle build files for Android, a bug in Cordova 6.5.0 can cause the build to fail with a rather cryptic error message:

A problem occurred evaluating root project 'android'.
> Could not get unknown property 'PLAY_SERVICES_VERSION' for object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.

It took me a while to figure out when and why it happens, and most importantly: how to fix it.

I encountered this problem with the latest version of the Google Maps plugin. When installing it, only the API keys need to be specified:

cordova plugin add cordova-plugin-googlemaps --save --variable API_KEY_FOR_ANDROID="(AndroidKey)" --variable API_KEY_FOR_IOS="(iOSKey)"

However, two more variables are configured with default values. You can find them in your project's config.xml file:

<plugin name="cordova-plugin-googlemaps" spec="~2.3.8">
    <variable name="API_KEY_FOR_ANDROID" value="(AndroidKey)" />
    <variable name="API_KEY_FOR_IOS" value="(iOSKey)" />
    <variable name="PLAY_SERVICES_VERSION" value="15.0.1" />
    <variable name="ANDROID_SUPPORT_V4_VERSION" value="26.1.0" />
</plugin>

Interestingly, the build will succeed if you then immediately try to build the project.

The problems occurs after you put the project into source control. It's a good practice to exclude the platforms and plugins subfolders from source control. They can easily be restored again after you retrieve the project from source control on a different computer using the following command:

cordova prepare

Although the command succeeds and recreates the missing platforms and plugins folders, the build will now fail with the following error:

A problem occurred evaluating root project 'android'.
> Could not get unknown property 'PLAY_SERVICES_VERSION' for object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.

You can find the culprit in the platform/android/project.properties file:

cordova.system.library.1=com.google.android.gms:play-services-maps:$PLAY_SERVICES_VERSION
cordova.system.library.2=com.google.android.gms:play-services-location:$PLAY_SERVICES_VERSION
cordova.system.library.3=com.android.support:support-core-utils:$ANDROID_SUPPORT_V4_VERSION

Notice the unresolved variable names $PLAY_SERVICES_VERSION and $ANDROID_SUPPORT_V4_VERSION instead of their values 15.0.1 and 26.1.0. This file is used by Gradle which of course doesn't know how to handle the unresolved variable names in the file nad therefore fails with the above mentioned error.

When the plugin was originally installed, these variables were correctly resolved. That's why the build succeeded. Because of a bug in Cordova 6.5.0 the cordova prepare command failed to replace these variables with their values when restoring the installed plugins.

In this version of Cordova, the problem can only be fixed by reinstalling the plugin using the cordova plugin add command. Fortunately, the bug was fixed in later versions of Cordova. Their cordova prepare command will correctly resolve the variable names, allowing the build to pass.

Your mileage may vary, but my current Cordova version of choice is 7.1.0. Bugs in 7.0.0 and breaking changes in 8.0.0 are preventing me from using any other version.

Copyright
Creative Commons License