Ionic & Firebase Image Upload Example
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.
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:
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);
}
);
});
}
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 {}