Codementor Events

Ionic & Firebase Image Upload Example

Published Oct 22, 2018

Everybody Has One

Firebase Realtime, Cloud Firestore & Storage

Simple demonstration of uploading a file to firebase storage from an ionic framework application. We are not uploading a base64 string, we are uploading a blob to the storage.

The storage is different from the Realtime database and the newer firebase Cloud Firestore.

Firebase offers two cloud-based, client-accessible database solutions that support realtime data syncing:

Realtime Database is Firebase’s original database. It’s an efficient, low-latency solution for mobile apps that require synced states across clients in realtime.

Cloud Firestore is Firebase’s new flagship database for mobile app development. It improves on the successes of the Realtime Database with a new, more intuitive data model. Cloud Firestore also features richer, faster queries and scales better than the Realtime Database.

Choose a database: Cloud Firestore or Realtime Database | Firebase
_If you're comfortable with a product in beta, use Cloud Firestore for your new projects. Cloud Firestore offers…_firebase.google.com

File Upload By The Books

The process for uploading the file is pretty straight forward and is explained much better in the firebase documentation; there is no magic involved.

See the code:

aaronksaunders/ionic4-firebase-storage
_File Upload from Ionic v4 App to Firebase Cloud Storage - aaronksaunders/ionic4-firebase-storage_github.com

uploadToFirebase(_imageBlobInfo) {
    console.log("uploadToFirebase");
    return new Promise((resolve, reject) => {
      let fileRef = firebase.storage()
                        .ref("images/" + _imageBlobInfo.fileName);

let uploadTask = fileRef.put(_imageBlobInfo.imgBlob);

uploadTask.on(
        "state_changed",
        (_snap: any) => {
          console.log(
            "progess " +
              (_snap.bytesTransferred / _snap.totalBytes) * 100
          );
        },
        _error => {
          console.log(_error);
          reject(_error);
        },
        () => {
          // completion...
          resolve(uploadTask.snapshot);
        }
      );
    });
  }

Upload Files on Web | Firebase
_Note: change your Firebase Security Rules for Cloud Storage to allow unauthenticated access. Since the default Google…_firebase.google.com

Magic of converting image from camera to blob for upload

This camera code for using the ionic-native camera plugin is copied directly from the ionic-native documentation

const options: CameraOptions = {
  quality: 80,
  destinationType: this.camera.DestinationType.FILE_URI,
  encodingType: this.camera.EncodingType.JPEG,
  mediaType: this.camera.MediaType.PICTURE
};

let cameraInfo = await this.camera.getPicture(options);

Be sure to include the cordova-file plugin and the cordova-camera plugin. The file-plugin is critical for converting the path to the file correctly so it can be converted to a blob for uploading

// FILE STUFF
  makeFileIntoBlob(_imagePath) {
    // INSTALL PLUGIN - cordova plugin add cordova-plugin-file
    return new Promise((resolve, reject) => {
      let fileName = "";
      this.file
        .resolveLocalFilesystemUrl(_imagePath)
        .then(fileEntry => {
          let { name, nativeURL } = fileEntry;

// get the path..
          let path = nativeURL
                      .substring(0, nativeURL.lastIndexOf("/"));

fileName = name;

// we are provided the name, so now read the file 
          // into a buffer
          return this.file.readAsArrayBuffer(path, name);
        })
        .then(buffer => {
          // get the buffer and make a blob to be saved
          let imgBlob = new Blob([buffer], {
            type: "image/jpeg"
          });
          
          // pass back blob and the name of the file for saving
          // into fire base
          resolve({
            fileName,
            imgBlob
          });
        })
        .catch(e => reject(e));
    });
  }

Things to notice in the code

Use the beta versions of the @ionic/native modules and you need to make sure you are using the “/ngx” path when importing the libraries.

"@ionic-native/camera": "^5.0.0-beta.15",
  "@ionic-native/core": "^5.0.0-beta.17",
  "@ionic-native/file": "5.0.0-beta.15",
  "@ionic-native/splash-screen": "5.0.0-beta.15",
  "@ionic-native/status-bar": "5.0.0-beta.15",

// notice the path for the import ends in ngx
import { Camera, CameraOptions } from "@ionic-native/camera/ngx";
import { File } from "@ionic-native/file/ngx";

You have to do the same when you import the module in app.module.ts

import { Camera } from '@ionic-native/camera/ngx';
import { File } from '@ionic-native/file/ngx';

@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule],
  providers: [
    File,
    Camera,
    StatusBar,
    SplashScreen,
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

Full Source Code To Example:

https://github.com/aaronksaunders/ionic4-firebase-storage

Discover and read more posts from Aaron Saunders
get started