Angular Material UI components for firebase storage
MIT License
Angular UI component for firebase authentication. This library is an angular module (including angular components and services) that allows to upload/download or event delete files from firebase storage within a firebase project.
Do you have any
question or suggestion ? Please do not hesitate to contact us!
Alternatively, provide a PR | open an appropriate issue here
If you like this project, support ngx-storage-firebaseui by starring â and sharing it ðĒ
any
important event occurred.ngx-auth-firebaseui
learn more
<ngx-storage-firebaseui-images>
used to upload imaged to firebase storage and sync them with firestorethe full tutorial guide can be found here
"peerDependencies": {
"@angular/core": "^9.x",
"@angular/animations": "^9.x",
"@angular/cdk": "^9.x",
"@angular/flex-layout": "^9.0.0-beta.29",
"@angular/material": "^9.x",
"@angular/fire": "5.4.x",
"firebase": "7.13.x",
}
In the following section, I will show you how to improve the user's experience regarding images
50x50,100x100,200x200,500x500,1000x1000,2000x2000
thumbs
(see below an example of an image directory in firebase storage)after installation
required
)firebase init
typescript
)firbease deploy --only functions
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import { ObjectMetadata } from 'firebase-functions/lib/providers/storage';
// tslint:disable-next-line:no-implicit-dependencies
import { Bucket, Storage } from '@google-cloud/storage';
// @ts-ignore
// tslint:disable-next-line:no-implicit-dependencies
import { GetSignedUrlResponse } from '@google-cloud/storage/build/src/file';
const path = require('path');
const os = require('os');
const fs = require('fs');
// tslint:disable-next-line:no-implicit-dependencies
const spawn = require('child-process-promise').spawn;
// tslint:disable-next-line:no-implicit-dependencies
const mkdirp = require('mkdirp-promise');
const storage = new Storage();
const firestore = admin.firestore();
const defaultStorage = admin.storage();
// const defaultBucket = defaultStorage.bucket();
/**
* Firebase cloud function to sync uploaded images to firebase storage bucket with firestore
*
* @author Anthony Nahas
* @since 03.2020
* @version 1.0
*/
export const syncImgsWithFirestore =
functions
.storage
.object()
.onFinalize(async (object: ObjectMetadata) => {
console.log('syncImgsWithFirestore is now running', object);
if (object && object.contentType && !object.contentType.includes('image')) {
console.log('exiting function');
return false;
}
let downloadURLs: any = null;
let downloadURL = null;
try {
downloadURLs = await getDownloadURL(object);
downloadURL = downloadURLs[0];
console.log('Download URL --> ', downloadURL, typeof downloadURL);
// downloadURL = downloadURL[0];
} catch (e) {
console.error('Error while getting download url', e);
}
const filePath = object.name;
console.log('file path -->', filePath);
// @ts-ignore
const pathSegments = filePath.split('/');
console.log('path segments --> ', pathSegments);
const indexOfID = pathSegments.indexOf('imgs');
console.log('indexOfID', indexOfID, pathSegments[indexOfID + 1]);
const imgID = pathSegments[indexOfID + 1];
const lastSegment = pathSegments[pathSegments.length - 1];
console.log('lastSegment', lastSegment);
const nameSegments = lastSegment.split('_');
console.log('nameSegments', nameSegments);
const resize = nameSegments[nameSegments.length - 1];
console.log('resize', resize);
const size = resize.split('x')[0];
console.log('size', size, typeof size);
// const img: NahausImage = {
// id: imgID,
// downloadURL,
// path: filePath
// };
const indexOfThumbs = pathSegments.indexOf('thumbs');
console.log('indexOfThumbs', indexOfThumbs);
let firestorePath: string;
if (indexOfThumbs !== -1) {
// the image is a thumbnail
firestorePath = pathSegments.splice(0, indexOfThumbs).join('/');
console.log('firestorePath', firestorePath);
const thumbsMapKey: string = `thumbs.${size}`;
return await firestore.doc(firestorePath).update({
[thumbsMapKey]: {
id: imgID,
downloadURL,
path: filePath
}
});
} else {
pathSegments.pop();
firestorePath = pathSegments.join('/');
console.log('firestorePath', firestorePath);
return await firestore.doc(firestorePath).set({
id: imgID,
downloadURL,
path: filePath
}, { merge: true });
}
});
function getDownloadURL(object: ObjectMetadata): Promise<GetSignedUrlResponse> | void {
if (!object.name) {
return;
}
const bucket: Bucket = defaultStorage.bucket();
const file = bucket.file(object.name);
// Get a signed URL for the file
return file.getSignedUrl({
action: 'read',
expires: '03-17-2025'
});
}
export const adjustOrientation = functions
.storage
.object()
.onFinalize(async (object) => {
const filePath = object.name;
const bucketName = object.bucket;
const metadata = object.metadata;
const tempLocalFile = path.join(os.tmpdir(), filePath);
const tempLocalDir = path.dirname(tempLocalFile);
const bucket = storage.bucket(bucketName);
if (object && object.contentType && !object.contentType.startsWith('image/')) {
console.log('This is not an image.');
return null;
}
if (metadata && metadata.autoOrient) {
console.log('This is already rotated');
return null;
}
return mkdirp(tempLocalDir).then(() => {
// Download file from bucket.
// @ts-ignore
return bucket.file(filePath).download({ destination: tempLocalFile });
}).then(() => {
console.log('The file has been downloaded to', tempLocalFile);
// Convert the image using ImageMagick.
return spawn('convert', [tempLocalFile, '-auto-orient', tempLocalFile]);
}).then(() => {
console.log('rotated image created at', tempLocalFile);
// @ts-ignore
metadata.autoOrient = true;
return bucket.upload(tempLocalFile, {
destination: filePath,
metadata: { metadata: metadata }
});
}).then(() => {
console.log('image uploaded to Storage at', filePath);
// Once the image has been converted delete the local files to free up disk space.
fs.unlinkSync(tempLocalFile);
console.log('Deleted local file', filePath);
return;
});
});
If Angular Material Design is not setup, just run ng add @angular/material
learn more
Now add the library via the angular schematics
ng add ngx-storage-firebaseui
ngx-storage-firebaseui
's module will be automatically imported to the root module (just replace PUT_YOUR_FIREBASE_API_KEY_HERE
with your firebase api key)ngx-storage-firebaseui
's assets will be automatically added the angular.json
fileInstall above dependencies via npm.
Now install ngx-storage-firebaseui
via:
npm install --save ngx-storage-firebaseui
npm i -s @angular/material @angular/cdk @angular/flex-layout @angular/forms @angular/animations @angular/router
Firebase deps
npm i -s firebase @angular/fire
-> continue by following the instructions
here
Once installed you need to import the main module:
import { NgxStorageFirebaseuiModule } from 'ngx-storage-firebaseui';
The only remaining part is to list the imported module in your application module. The exact method will be slightly
different for the root (top-level) module for which you should end up with the code similar to (notice NgxStorageFirebaseuiModule .forRoot()
):
and then from your Angular AppModule
:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
// Import your library
import { NgxStorageFirebaseuiModule } from 'ngx-storage-firebaseui';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
// Specify the ngx-storage-firebaseui library as an import
NgxStorageFirebaseuiModule.forRoot({
apiKey: 'your-firebase-apiKey',
authDomain: 'your-firebase-authDomain',
databaseURL: 'your-firebase-databaseURL',
projectId: 'your-firebase-projectId',
storageBucket: 'your-firebase-storageBucket',
messagingSenderId: 'your-firebase-messagingSenderId'
}),
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Other modules in your application can simply import NgxStorageFirebaseuiModule
:
import { NgxStorageFirebaseuiModule } from 'ngx-storage-firebaseui';
@NgModule({
declarations: [OtherComponent, ...],
imports: [NgxStorageFirebaseuiModule, ...],
})
export class OtherModule {
}
Note:If you are using
SystemJS
, you should adjust your configuration to point to the UMD bundle. In your systemjs config file,map
needs to tell the System loader where to look forngx-storage-firebaseui
:
{
'ngx-storage-firebaseui';: 'node_modules/ngx-storage-firebaseui/bundles/ngx-storage-firebaseui.umd.js',
}
Once the library is imported, you can use its components, directives and pipes in your Angular application:
<ngx-storage-firebaseui-images></ngx-storage-firebaseui-images>
see the usage
<ngx-storage-firebaseui-images></ngx-storage-firebaseui-images>
see the api
option | bind | type | default | description |
---|---|---|---|---|
path | Input() |
string |
- | path to store the image into firebase storage as well as in the firestore |
load | Input() |
boolean |
true |
whether to load the uploaded images from firebase |
addButtonTooltipText | Input() |
string |
add picture |
text of the add button tooltip |
onLoad | Output() |
number |
- | called when the images are loaded from firestore |
onImageUploaded | Output() |
number |
- | called when an image is uploaded to firebase storage |
onImageSelectedAtIndex | Output() |
number |
- | called when an image is selected / clicked |
Built by and for developers âĪïļ we will help you ð
This project is supported by jetbrains with 1 ALL PRODUCTS PACK OS LICENSE incl. webstorm
Copyright (c) 2020 Anthony Nahas. Licensed under the MIT License (MIT)