Capacitor: Error: Can't resolve 'cordova/exec' when using Cordova plugin

Created on 4 Dec 2018  路  11Comments  路  Source: ionic-team/capacitor

I am trying to use cordova-plugin-mauron85-background-geolocation so I can collect geolocation data while the app is in the background (see #516).

However following these instructions ends up giving me a build error: Error: Can't resolve 'cordova/exec'. I believe this is the offending line, however running npm install cordova does not fix the issue.

Is there something really obvious I'm missing?

Most helpful comment

For anyone else wanting to use the cordova-plugin-mauron85-background-geolocation plugin, this is what I ended up doing to get it working on Android:

  1. npm install cordova-plugin-mauron85-background-geolocation
  2. npm install cordova-android-play-services-gradle-release (optional, fixes compatibility with Capacitor's PushNotification plugin)
  3. npx cap copy
  4. Add suitable values to android/app/src/main/res/values/strings.xml:
    <string name="mauron85_bgloc_content_authority">com.bundle.id</string>
    <string name="mauron85_bgloc_account_type">com.bundle.id.account</string>
    <string name="mauron85_bgloc_account_name">My App</string>
  1. Use in script like so:
    const { BackgroundGeolocation } = window

    BackgroundGeolocation.on('location', function(location) {
      // {
      //   accuracy: 21
      //   altitude: 15
      //   bearing: 0
      //   id: 3
      //   isFromMockProvider: false
      //   latitude: -33.95674337167293
      //   locationProvider: 0
      //   longitude: 150.98079233430326
      //   mockLocationsEnabled: false
      //   provider: "gps"
      //   speed: 0.14999999105930328
      //   time: 1543912755527
      // }

      const {
        latitude,
        longitude,
        altitude,
        accuracy,
      } = location

      this.accuracy = accuracy

      this.path.features[0].geometry.coordinates.push([
        longitude,
        latitude,
        altitude,
      ])
    })


    BackgroundGeolocation.start()

All 11 comments

Webpack stack trace:

 ERROR  ModuleNotFoundError: Module not found: Error: Can't resolve 'cordova/exec' in '/Users/me/proj/node_modules/cordova-plugin-mauron85-background-geolocation/www'
ModuleNotFoundError: Module not found: Error: Can't resolve 'cordova/exec' in '/Users/me/proj/node_modules/cordova-plugin-mauron85-background-geolocation/www'
    at factory.create (/Users/me/proj/node_modules/webpack/lib/Compilation.js:821:10)
    at factory (/Users/me/proj/node_modules/webpack/lib/NormalModuleFactory.js:397:22)
    at resolver (/Users/me/proj/node_modules/webpack/lib/NormalModuleFactory.js:130:21)
    at asyncLib.parallel (/Users/me/proj/node_modules/webpack/lib/NormalModuleFactory.js:224:22)
    at /Users/me/proj/node_modules/neo-async/async.js:2825:7
    at /Users/me/proj/node_modules/neo-async/async.js:6886:13
    at normalResolver.resolve (/Users/me/proj/node_modules/webpack/lib/NormalModuleFactory.js:214:25)
    at doResolve (/Users/me/proj/node_modules/enhanced-resolve/lib/Resolver.js:184:12)
    at hook.callAsync (/Users/me/proj/node_modules/enhanced-resolve/lib/Resolver.js:238:5)
    at _fn0 (eval at create (/Users/me/proj/node_modules/tapable/lib/HookCodeFactory.js:32:10), <anonymous>:15:1)
    at resolver.doResolve (/Users/me/proj/node_modules/enhanced-resolve/lib/UnsafeCachePlugin.js:37:5)
    at hook.callAsync (/Users/me/proj/node_modules/enhanced-resolve/lib/Resolver.js:238:5)
    at _fn0 (eval at create (/Users/me/proj/node_modules/tapable/lib/HookCodeFactory.js:32:10), <anonymous>:15:1)
    at hook.callAsync (/Users/me/proj/node_modules/enhanced-resolve/lib/Resolver.js:238:5)
    at _fn0 (eval at create (/Users/me/proj/node_modules/tapable/lib/HookCodeFactory.js:32:10), <anonymous>:12:1)
    at resolver.doResolve (/Users/me/proj/node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js:42:38)

I tried using the plugin from my source like so:

import BackgroundGeolocation from 'cordova-plugin-mauron85-background-geolocation'

But it occured to me that perhaps I should access it via the window.cordova.plugins object. Running on my Android device, however, that object is undefined.

Is there some way I need to configure Capacitor to "know" that this plugin is installed? Or does it magically discover and install cordova plugins on npx cap sync?

Maybe this is intentional behaviour, but

ios/App/public/cordova.js
ios/App/public/cordova_plugins.js
android/app/build/intermediates/assets/debug/public/cordova.js
android/app/build/intermediates/assets/debug/public/cordova_plugins.js

are empty files.

I think I've found my problem...I installed the cordova plugin to devDependencies instead of dependencies, so Capacitor wasn't registering it

For anyone else wanting to use the cordova-plugin-mauron85-background-geolocation plugin, this is what I ended up doing to get it working on Android:

  1. npm install cordova-plugin-mauron85-background-geolocation
  2. npm install cordova-android-play-services-gradle-release (optional, fixes compatibility with Capacitor's PushNotification plugin)
  3. npx cap copy
  4. Add suitable values to android/app/src/main/res/values/strings.xml:
    <string name="mauron85_bgloc_content_authority">com.bundle.id</string>
    <string name="mauron85_bgloc_account_type">com.bundle.id.account</string>
    <string name="mauron85_bgloc_account_name">My App</string>
  1. Use in script like so:
    const { BackgroundGeolocation } = window

    BackgroundGeolocation.on('location', function(location) {
      // {
      //   accuracy: 21
      //   altitude: 15
      //   bearing: 0
      //   id: 3
      //   isFromMockProvider: false
      //   latitude: -33.95674337167293
      //   locationProvider: 0
      //   longitude: 150.98079233430326
      //   mockLocationsEnabled: false
      //   provider: "gps"
      //   speed: 0.14999999105930328
      //   time: 1543912755527
      // }

      const {
        latitude,
        longitude,
        altitude,
        accuracy,
      } = location

      this.accuracy = accuracy

      this.path.features[0].geometry.coordinates.push([
        longitude,
        latitude,
        altitude,
      ])
    })


    BackgroundGeolocation.start()

Yeah, you shouldn't do import BackgroundGeolocation from 'cordova-plugin-mauron85-background-geolocation' to use the plugin, that's what cause the problem.

But the plugin types were not ok neither, so you couldn't use autocompletion.
I've sent a PR to his repo fixing the types so you can use them by adding this to your .ts file /// <reference types="cordova-plugin-mauron85-background-geolocation" />, so you don't need this const { BackgroundGeolocation } = window and autocompletion works.

@jcesarmobile I'm actually using ES6, not typescript, but cheers!

@diachedelic It doesn't work for me. The window inside the Cordova app has no BackgroundGeolocation property. Is there anything else I should check? I am stuck for quite some time now, just to get the plugin to work.

@PhillippOhlandt can you access any other cordova plugins?

This worked for me, based on this snippet from @mauron85:

import { BackgroundGeolocationPlugin }  from '@mauron85/cordova-plugin-background-geolocation';
declare const BackgroundGeolocation: BackgroundGeolocationPlugin;

// ... Usage
BackgroundGeolocation.configure({...});
Was this page helpful?
0 / 5 - 0 ratings

Related issues

danielsogl picture danielsogl  路  3Comments

nicobytes picture nicobytes  路  3Comments

json-derulo picture json-derulo  路  3Comments

gnesher picture gnesher  路  3Comments

peterpeterparker picture peterpeterparker  路  3Comments