Cant "Use Photo" with Capacitor Camera Plugin

Hey!

I want to implement a simple camera feature. The user should be able to take a photo, which is then passed on to firebase storage. Uploading shouldn’t be a big problem, although when pressing “Use Photo” after taking it, the app throws an error: “[error] ERROR {}” in the Xcode console log. I am trying to figure out what the issue could be but can’t seem to find it.

Here is my simplified code for taking and uploading the image:

// Take photo
  pickOrTakePhoto() {
    console.log("About to take photo");
    return new Promise(async (resolve, reject) => {
      try {
        const image = await Camera.getPhoto({
          quality: 90,
          resultType: CameraResultType.DataUrl,
          source: CameraSource.Prompt,
        });
        console.log("Got through. "); // <-- This doesn't fire so the problem should be the getPhoto() function.
        const storageRef = this.storage.ref('/files/' + new Date().getTime().toString());
        const uploadTask = await storageRef.put(image.dataUrl, {contentType: 'image/' + image.format});
        resolve(uploadTask);
      }
      catch (error) {
        console.error("Error when processing photo: " + error);
        reject(error);
      }
    });
  }

Here is a copy of the error I get in the Xcode console log:

[error] - Unable to load PWA Element 'pwa-camera-modal'. See the docs: https://capacitorjs.com/docs/pwa-elements.
2021-07-08 17:57:33.665785+0200 App[12210:3921790] [Camera] Failed to read exposureBiasesByMode dictionary: Error Domain=NSCocoaErrorDomain Code=4864 "*** -[NSKeyedUnarchiver _initForReadingFromData:error:throwLegacyExceptions:]: data is NULL" UserInfo={NSDebugDescription=*** -[NSKeyedUnarchiver _initForReadingFromData:error:throwLegacyExceptions:]: data is NULL}
⚡️  [error] - ERROR {}

OBS! The error about not being able to load the PWA element shouldn’t play a role, because I run the app in the native app on my iPhone X.

One thing to note is that CameraResultType.Uri seems to get through, meaning the console.log after taking the photo gets logged. The only options not working are CameraResultType.Base64 and CameraResultType.DataUrl, which I need to upload to firebase.

Ionic 5 with Capacitor 3

I really appreciate all the help I can get! Thanks!

If you are running from Xcode but seeing that pwa-elements message, it means the app is using the web version of the plugin instead of the native version.

Do you have WKAppBoundDomains key in your Info.plist? That can make native plugins not work.

Hej @jcesarmobile , unfortunately not. I haven’t changed anything in Info.plist since creating the project.

On iOS that’s the only thing that I’m aware of that can make native use web plugins when using Capacitor 3. If you provide a sample app I can take a look.

  1. The code isn’t that complex. I run the pickOrTakePhoto() function, which is located in a service, in my simple welcome-prompt page like this:
this.mainService.pickOrTakePhoto().then(image => {
      console.log(image);
});
  1. In my service I import the Capacitor Camera Plugin like this:
import { Camera, CameraPhoto, CameraResultType, CameraSource } from '@capacitor/core';
  1. Here is my package.json file:
{
  "name": "ihelp",
  "version": "0.0.1",
  "author": "Ionic Framework",
  "homepage": "https://ionicframework.com/",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/common": "~9.1.6",
    "@angular/core": "~9.1.6",
    "@angular/fire": "^6.0.2",
    "@angular/forms": "~9.1.6",
    "@angular/platform-browser": "~9.1.6",
    "@angular/platform-browser-dynamic": "~9.1.6",
    "@angular/router": "~9.1.6",
    "@capacitor/android": "^2.4.7",
    "@capacitor/core": "2.4.5",
    "@capacitor/ios": "^2.4.7",
    "@ionic-native/aes-256": "^5.33.0",
    "@ionic-native/camera": "^5.33.0",
    "@ionic-native/core": "^5.33.0",
    "@ionic-native/facebook": "^5.33.0",
    "@ionic-native/file": "^5.33.0",
    "@ionic-native/google-plus": "^5.33.0",
    "@ionic-native/in-app-browser": "^5.33.0",
    "@ionic-native/in-app-purchase-2": "^5.33.0",
    "@ionic-native/media": "^5.33.0",
    "@ionic-native/media-capture": "^5.33.0",
    "@ionic-native/onesignal": "^5.33.0",
    "@ionic-native/sign-in-with-apple": "^5.33.1",
    "@ionic-native/splash-screen": "^5.33.0",
    "@ionic-native/status-bar": "^5.33.0",
    "@ionic-native/video-capture-plus": "^5.33.0",
    "@ionic/angular": "^5.6.7",
    "@ionic/pwa-elements": "^3.0.2",
    "bad-words": "^3.0.4",
    "capacitor-apple-login": "git+https://github.com/rlfrahm/capacitor-apple-login.git",
    "chart.js": "^2.9.4",
    "cordova-plugin-aes256-encryption": "^2.0.1",
    "cordova-plugin-facebook4": "^6.4.0",
    "cordova-plugin-googleplus": "^8.5.2",
    "cordova-plugin-inappbrowser": "^5.0.0",
    "cordova-plugin-media-capture": "^3.0.3",
    "cordova-plugin-purchase": "^10.5.3",
    "cordova-plugin-sign-in-with-apple": "^0.1.2",
    "crypto-js": "^4.0.0",
    "firebase": "^8.6.1",
    "npm": "^7.12.1",
    "onesignal-cordova-plugin": "^2.11.3",
    "rxjs": "~6.5.1",
    "tslib": "^2.1.0",
    "zone.js": "~0.10.2"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^0.901.15",
    "@angular/cli": "^9.1.15",
    "@angular/compiler": "^9.1.13",
    "@angular/compiler-cli": "^9.1.13",
    "@angular/language-service": "^9.1.13",
    "@capacitor/cli": "2.4.5",
    "@ionic/angular-toolkit": "^2.3.3",
    "@ionic/lab": "3.2.10",
    "@types/jasmine": "^3.7.4",
    "@types/jasminewd2": "^2.0.9",
    "@types/node": "^12.20.13",
    "cocoapods": "0.0.0",
    "codelyzer": "^5.1.2",
    "cordova-android": "^9.1.0",
    "cordova-ios": "^6.2.0",
    "cordova-plugin-camera": "^5.0.1",
    "cordova-plugin-compat": "^1.2.0",
    "cordova-plugin-device": "^2.0.3",
    "cordova-plugin-file": "^6.0.2",
    "cordova-plugin-ionic-keyboard": "^2.2.0",
    "cordova-plugin-media": "^5.0.3",
    "cordova-plugin-splashscreen": "^5.0.4",
    "cordova-plugin-statusbar": "^2.4.3",
    "cordova-plugin-whitelist": "^1.3.4",
    "jasmine-core": "~3.5.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~5.0.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage-istanbul-reporter": "~2.1.0",
    "karma-jasmine": "~3.0.1",
    "karma-jasmine-html-reporter": "^1.6.0",
    "protractor": "~5.4.3",
    "ts-node": "~8.3.0",
    "tslint": "^6.1.3",
    "typescript": "~3.8.3"
  },
  "description": "An Ionic project",
  "cordova": {
    "plugins": {
      "cordova-plugin-media": {},
      "cordova-plugin-camera": {},
      "cordova-plugin-file": {},
      "nl.x-services.plugins.videocaptureplus": {},
      "cordova-plugin-whitelist": {},
      "cordova-plugin-statusbar": {},
      "cordova-plugin-device": {},
      "cordova-plugin-splashscreen": {},
      "cordova-plugin-ionic-webview": {
        "ANDROID_SUPPORT_ANNOTATIONS_VERSION": "27.+"
      },
      "cordova-plugin-ionic-keyboard": {}
    },
    "platforms": [
      "android",
      "ios"
    ]
  }
}

OBS! I haven’t changed anything in it since creating this project.

  1. Also keep in mind, that for the CameraOptions, CameraResultType.Uri is working, while .Base64 and .DataUrl aren’t.

Thank you for willing to help!

Of course the code is not complex, but you are clearly doing something wrong, so I asked for a real app so I could see what’s wrong, but the snippets of code you have provided are enough.

First of all you said you were using Capacitor 3. but that package.json shows Capacitor 2 dependencies.

Second, you are using the plugin in a wrong way, if you check v2 docs, you should see how to use them properly:

You shouldn’t import Camera from core, but Plugins and then pick the Camera plugin from Plugins object like this.

import { Plugins, CameraPhoto, CameraResultType, CameraSource } from '@capacitor/core';

const { Camera } = Plugins;

Using it like you are doing will use the web version, but I didn’t tell you that because you said you were in Capacitor 3 and that problems is no longer present in Capacitor 3 since you import Camera from the new camera plugin instead of from core.

2 Likes