Cordova-plugin-firebasex: [after_prepare.js] TypeError: (plugin.variable || []).forEach is not a function

Created on 11 Nov 2019  路  2Comments  路  Source: dpa99c/cordova-plugin-firebasex

Bug report

Current behavior:

During installation of cordova-plugin-firebasex, it runs the after_prepare.js script. If a plugin defined in config.xml has exactly one variable defined, like this:

<plugin name="cordova.plugins.diagnostic" spec="~5.0.0">
  <variable name="ANDROID_SUPPORT_VERSION" value="28.+" />
</plugin>

Then the script will throw an error and cordova will not complete its installation:

Executing script found in plugin cordova-plugin-firebasex for hook "after_prepare": plugins/cordova-plugin-firebasex/scripts/after_prepare.js
(plugin.variable || []).forEach is not a function
TypeError: (plugin.variable || []).forEach is not a function
    at /Users/cordova-developer/dev/cordova-plugin-firebasex-test/plugins/cordova-plugin-firebasex/scripts/after_prepare.js:49:33
    at Array.forEach (<anonymous>)
    at parsePluginVariables (/Users/cordova-developer/dev/cordova-plugin-firebasex-test/plugins/cordova-plugin-firebasex/scripts/after_prepare.js:48:34)
    at module.exports (/Users/cordova-developer/dev/cordova-plugin-firebasex-test/plugins/cordova-plugin-firebasex/scripts/after_prepare.js:73:3)
    at runScriptViaModuleLoader (/Users/cordova-developer/.nvm/versions/node/v12.13.0/lib/node_modules/cordova/node_modules/cordova-lib/src/hooks/HooksRunner.js:181:32)
    at runScript (/Users/cordova-developer/.nvm/versions/node/v12.13.0/lib/node_modules/cordova/node_modules/cordova-lib/src/hooks/HooksRunner.js:157:16)
    at /Users/cordova-developer/.nvm/versions/node/v12.13.0/lib/node_modules/cordova/node_modules/cordova-lib/src/hooks/HooksRunner.js:125:20

If I add a second fake variable to the plugin with only one variable, then the after_prepare.js script runs without errors. Like this:

<plugin name="cordova.plugins.diagnostic" spec="~5.0.0">
  <variable name="ANDROID_SUPPORT_VERSION" value="28.+" />
  <variable name="fake_variable_for_cordova_plugin_firebasex_7_0_0_support" value="ok" />
</plugin>

I think this is related to the xml-js conversion process. If if there are two or more child nodes of the same type, they become an array. But if there is only one child node of that type, it becomes an object. (See the Compact JSON example at the top of the page and compare <title> and <todo> conversion.)

Another drawback of compact output is the resultant element can be an object or an array and therefore makes the client code a little awkward in terms of the extra check needed on object type before processing. (source)

Expected behavior:

The after_prepare script should handle various config.xml files smoothly.

Steps to reproduce:

  1. Clone this repository based on the firebasex demo project: https://github.com/patrick-entinux/cordova-plugin-firebasex-test-after-prepare
  2. run npm install
  3. run npx cordova prepare ios --verbose and the above error should appear

Environment information

$ cordova -v                                        
9.0.0 ([email protected])

$ cordova platform ls
Installed platforms:
  ios 5.0.1
Available platforms: 
  android ^8.0.0
  browser ^6.0.0
  electron ^1.0.0
  osx ^5.0.0
  windows ^7.0.0

$ cordova plugin ls                                 
cordova-custom-config 5.1.0 "cordova-custom-config"
cordova-plugin-androidx 1.0.2 "cordova-plugin-androidx"
cordova-plugin-androidx-adapter 1.1.0 "cordova-plugin-androidx-adapter"
cordova-plugin-customfcmreceiver 1.0.0 "Custom FCM Receiver"
cordova-plugin-firebasex 7.0.0 "Google Firebase Plugin"
cordova-plugin-whitelist 1.3.4 "Whitelist"
cordova.plugins.diagnostic 5.0.1 "Diagnostic"

$ sw_vers            
ProductName:    Mac OS X
ProductVersion: 10.13.6
BuildVersion:   17G9016

$ node -v                                                                          
v12.13.0

Related code:

The related code is this plugin.variable line in after_prepare.js. It assumes that plugin.variable is always an array or undefined, but it can also be an object if there is exactly one variable defined.

var parsePluginVariables = function(){
    var config = Utilities.parseConfigXml();
    (config.widget.plugin || []).forEach(function(plugin){
        (plugin.variable || []).forEach(function(variable){
            if((plugin._attributes.name === PLUGIN_ID || plugin._attributes.id === PLUGIN_ID) && variable._attributes.name && variable._attributes.value){
                pluginVariables[variable._attributes.name] = variable._attributes.value;
            }
        });
    });

    var packageJSON = Utilities.parsePackageJson();
    if(packageJSON.cordova && packageJSON.cordova.plugins){
        for(const pluginId in packageJSON.cordova.plugins){
            if(pluginId === PLUGIN_ID){
                for(const varName in packageJSON.cordova.plugins[pluginId]){
                    var varValue = packageJSON.cordova.plugins[pluginId][varName];
                    pluginVariables[varName] = varValue;
                }
            }
        }
    }
};
bug build issue

Most helpful comment

Nearly the same thing happens if there is only one plugin configuration present in config.xml. I just opened a PR #219 to fix this issue.

All 2 comments

Nearly the same thing happens if there is only one plugin configuration present in config.xml. I just opened a PR #219 to fix this issue.

Resolved by #219 (thanks to @mahnuh)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

REPTILEHAUS picture REPTILEHAUS  路  6Comments

leabdalla picture leabdalla  路  7Comments

xurdep picture xurdep  路  5Comments

luboslav picture luboslav  路  6Comments

tux240 picture tux240  路  3Comments