Ionic_vue + capacitor + native plugin = does not work (

Hi All!

npm install cordova-plugin-device --save
npm install @ionic-native/device --save

main.js:

import { Device } from ‘@ionic-native/device/ngx’;
Vue.use(Device);

component.vue:

console.log(Device) =>
Device()​
annotations: Array [ {} ]
​length: 0
​name: “Device”
platforms: Array(5) [ “Android”, “Browser”, “iOS”, … ]
plugin: “cordova-plugin-device”
pluginName: “Device”
pluginRef: “device”
prototype: Object { constructor: Device(), cordova: Getter & Setter, model: Getter & Setter, … }
repo: “https://github.com/apache/cordova-plugin-device
: IonicNativePlugin()

BUT: there is no neither window.device, nor this.device

If I do
const device = new Device();
console.log(device) => all properties are nulls, device.platform etc

I tried to use few Ionic native plugins this way with VueJS, but no luck (
But some Capacitor plugins are works, e.g. Modals

Please help.

I’m experiencing a similar problem trying to get the Ionic Native Barcode Scanner to work inside my Ionic Vue project with Capacitor.

The Capacitor docs show how to use native plugins with Ionic Angular, but can’t find any examples or instructions on making them work with Ionic Vue with Capacitor.

When I try to import { BarcodeScanner } from '@ionic-native/barcode-scanner/ngx'; , I get Can't resolve '@angular/core' in '/node_modules/@ionic-native/barcode-scanner/ngx'.

But when I import { BarcodeScanner } from '@ionic-native/barcode-scanner'; , I get cordova_not_available.

Do you need to use something like https://www.npmjs.com/package/vue-cordova-plugin so that cordova is available? Or is there a way to use @ionic-native/barcode-scanner? Or should I use phonegap-plugin-barcodescanner directly instead? :thinking:

@aaronksaunders do you have any suggestions on how to use Cordova plugins inside Ionic 4 + Vue project?

PS thanks for your previous help sharing your Vue examples :+1:

npm install phonegap-plugin-barcodescanner

then follow instructions from plugin website…

see… https://github.com/aaronksaunders/capacitor-vue-ionicv4-app, look in Home.vue

Thanks for the reply @aaronksaunders! When I try calling cordova.plugins.barcodeScanner.scan, I get cordova is not defined.

Looking through capacitor-vue-ionicv4-app, I don’t see any place where you’re importing phonegap-plugin-barcodescanner besides being a dependency in package.json?

  • it is installed through the npm install command

I’m having a similar problem running capacitor-vue-ionicv4-app in the browser. The Capacitor plugin works fine, but the Cordova plugin does not.

sorry… for late follow up, did you get this working - it is not going to fine cordova in the web browser, the barcodescanner will only work on device

Thanks for reply @aaronksaunders, I was wondering whether phonegap-plugin-barcodescanner worked in the browser. I was uncertain since their website says:

Supported Platforms

  • Android
  • iOS
  • Windows (Windows/Windows Phone 8.1 and Windows 10)
  • Browser

I’ve been able to get vue-qrcode-reader working in the browser and mobile. However it only supports QR codes and does not handle regular barcodes.

What are my options for barcode scanning in browser and mobile? Is there a Capacitor option?

Hi @dalezak.

I’m in the same situation that you, in my case, also using vue-qrcode-reader, but in documentation says not working in chrome IOS. In your case works? If yes, I will use this.

Thanks.

@7Brito in the end I had to implement multiple plugins to get both qrcode and barcode to work on iOS, Android and PWA for my Ionic + Vue + Capacitor project.

Note, I ran into a bug in vue-quagga so just implemented quaggaJS directly. I also used phonegap-plugin-barcodescanner for both barcode and qrcode for iOS and Android, but specify formats config to distinguish between each.

PWA

Barcode - quaggaJS

import Quagga from 'quagga';
<div id="interactive" class="viewport scanner">
  <video />
  <canvas class="drawingBuffer" />
</div>
data() {
  return {
    width: 0,
    height: 0,
    readers: [
      'ean_reader',
      'upc_reader',
      'code_128_reader' 
    ]
  }
},
computed: {
  config() {
    return { 
      inputStream: {
        type: 'LiveStream',
        constraints: {
          width: this.width,
          height: this.height,
          facingMode: 'environment',
          aspectRatio: { 
            min: 1, 
            max: 2 
          },
        },
      },
      locator: {
        patchSize: 'medium',
        halfSample: true,
      },
      numOfWorkers: 2,
      frequency: 10,
      decoder: {
        readers: [
          'ean_reader',
          'upc_reader',
          'code_128_reader' 
        ]
      },
      locate: true
    }
  }
},
mounted() {
  setTimeout(() => {
    this.loadCanvas();
    this.loadScanner();
  }, 1000);
},
destroyed() {
  Quagga.stop();
},
methods: {
  loadCanvas() {
    let ratio = 0.7;
    let container = document.querySelector("#interactive");
    this.width = container.offsetWidth;
    this.height = container.offsetWidth * ratio;
  },
  loadScanner() {
    Quagga.init(this.config, (err) => {
      if (err) {
        return console.error(err);
      }
      Quagga.start();
    });
    Quagga.onDetected(this.onDetected);
    Quagga.onProcessed(this.onProcessed);
  },
  onDetected(result) {
    console.log('onDetected', result);
  },
  onProcessed(result) {
    if (result) {
      let drawingCtx = Quagga.canvas.ctx.overlay;
      let drawingCanvas = Quagga.canvas.dom.overlay;
      if (result.boxes) {
        drawingCtx.clearRect(
          0,
          0,
          parseInt(drawingCanvas.getAttribute('width')),
          parseInt(drawingCanvas.getAttribute('height'))
        );
        result.boxes
          .filter(function(box) {
            return box !== result.box;
          })
          .forEach(function(box) {
            Quagga.ImageDebug.drawPath(box, { x: 0, y: 1 }, drawingCtx, {
              color: 'green',
              lineWidth: 2,
            });
          });
      }
      if (result.box) {
        Quagga.ImageDebug.drawPath(result.box, { x: 0, y: 1 }, drawingCtx, {
          color: '#00F',
          lineWidth: 2,
        });
      }
      if (result.codeResult && result.codeResult.code) {
        Quagga.ImageDebug.drawPath(
          result.line,
          { x: 'x', y: 'y' },
          drawingCtx,
          { color: 'red', lineWidth: 3 }
        );
      }
    }
  }
}

QRCode - vue-qrcode-reader

import { QrcodeStream, QrcodeDropZone, QrcodeCapture } from "vue-qrcode-reader";
<qrcode-drop-zone @decode="onScan" @init="onError">
  <qrcode-stream @decode="onScan" @init="onInit"></qrcode-stream>
</qrcode-drop-zone>
<qrcode-capture v-if="noStreamApiSupport" @decode="onScan" /> 
async onInit(promise) {
  await promise;
},
onScan(data) {
  console.log('onScan', data);
},
onError(promise) {
  promise.catch(console.error);
}

iOS / Android

Barcode - phonegap-plugin-barcodescanner

async scanBarcode(frontCamera=true, flipCamera=true, torchButton=true) {
    return new Promise((resolve, reject) => {
        cordova.plugins.barcodeScanner.scan(
            (result) => {
                resolve(result.text);
            },
            (error) => {
                reject(error);
            },
            {
                preferFrontCamera: frontCamera, 
                showFlipCameraButton: flipCamera, 
                showTorchButton: torchButton, 
                torchOn: false, 
                saveHistory: false, 
                prompt: "Place barcode inside scan area", 
                resultDisplayDuration: 500, 
                formats: "ALL_1D,AZTEC,CODABAR,CODE_39,CODE_93,CODE_128,EAN_8,EAN_13,UPC_A,UPC_E,UPC_EAN_EXTENSION,DATA_MATRIX,ITF,MAXICODE,MSI,RSS_14,PDF_417,PLESSEY", // default: all but PDF_417 and RSS_EXPANDED
                disableAnimations: true, 
                disableSuccessBeep: false 
            }
        );
    });
}

QRCode - phonegap-plugin-barcodescanner

async scanQrcode(frontCamera=true, flipCamera=true, torchButton=true) {
    return new Promise((resolve, reject) => {
        cordova.plugins.barcodeScanner.scan(
            (result) => {
                resolve(result.text);
            },
            (error) => {
                reject(error);
            },
            {
                preferFrontCamera: frontCamera, 
                showFlipCameraButton: flipCamera, 
                showTorchButton: torchButton, 
                torchOn: false, 
                saveHistory: false, 
                prompt: "Place qrcode inside scan area", 
                resultDisplayDuration: 500, 
                formats: "QR_CODE", 
                disableAnimations: true, 
                disableSuccessBeep: false 
            }
        );
    });
}

Hope this helps! Big thanks to @aaronksaunders for his capacitor-vue-ionicv4-app example :+1: