4.1.2 • Published 3 years ago
multer-firebase-storage v4.1.2
multer-firebase-storage
Multer Storage Engine for Firebase
Installation
npm install multer-firebase-storage
Usage
Using Express:
const Express = require('express')
const Multer = require('multer')
const FirebaseStorage = require('multer-firebase-storage')
const app = new Express()
const multer = Multer({
storage: FirebaseStorage({
bucketName: 'your-default-bucket',
credentials: {
clientEmail: 'your-firebase-client-email',
privateKey: 'your private key',
projectId: 'your-project-id'
}
})
})
app.post('/file', multer.single('file'), (req, res) => {
res.status(201).json(req.file)
})
app.listen(3000, () => {
console.log('Example app listening on port 3000!')
})Tweaks and options
Firebase Storage supports the following setup options:
{
bucketName: string;
credentials: string | { projectId: string, privateKey: string, clientEmail: string }
directoryPath?: string
mimeMap?: {
[fileName: string]: string
}
appName?: string
namePrefix?: string
nameSuffix?: string
unique?: boolean
public?: boolean
hooks: {
[hookName: string]: function
}
}Required options
bucketName: The name of the bucket to upload to.credentials: The credentials to use for authentication. It can be a refresh token string or the Firebase credentials object (just like the firebase admin SDK requests).- Credentials can be provided by reading the Firebase Service Account JSON file and passing the contents as an object
- Credentials can be a set of the following properties:
projectId,privateKey,clientEmailwhich can be obtained by the Firebase console. - Note: The
privateKeyfield needs to be in the same format as in the JSON file.
Optional options
directoryPath: Will be prepended to the file name to include the file in a subdirectory.- For example: if the file name is
image.jpgand the directory path isimages, the resulting file name will beimages/image.jpg. There's no need to add a trailing slash.
- For example: if the file name is
appName: Firebase allows only a single instance of its admin SDK to be executed per app. If you need more than one, specify the name of the app you want to use. Remember it needs to be unique in the applicationnamePrefix: The prefix to be added to the file name.- This will append a string before the file name, but after the directory path. For example: if the file name is
image.jpgand the prefix ispreview_, the resulting file name will bepreview_image.jpg.
- This will append a string before the file name, but after the directory path. For example: if the file name is
nameSuffix: The suffix to be added to the file name.- This will append a string after the file name, but before the file extension. For example: if the file name is
image.jpgand the suffix is_final, the resulting file name will beimage_final.jpg.
- This will append a string after the file name, but before the file extension. For example: if the file name is
unique: If set totrue, the file name will be unique by generating a time-based hash that will be appended to the end of the file name (afternameSuffixand before the file extension). If set tofalse, the file name will be the same as the original file name.- For example: if the file name is
image.jpgand the suffix is_finalanduniqueistrue, the resulting file name will beimage_final<somehashhere>.jpg.
- For example: if the file name is
public: If set totrue, the file will be made public and the public URL will be returned. If set tofalse, the file will be private.hooks: Where you can define lifecycle hooks
Returned data
After a successful insertion, all returned data will be appended to the req.file object. Besides the original Multer properties, the following properties will be added:
fileRef: A reference to the Firebase Storage file object. You can use that to manipulate the file after the upload has been done.- Common operations to this reference are: generating signed URLs, deleting the file, etc.
- The type of this property is the same as if you were using the Firebase Storage SDK directly with
firebase.storage().bucket().file(filename)
path: The path of the file in the bucket.bucket: The name of the bucket.bucketRef: A reference to the Firebase Storage bucket object. You can use that to manipulate the bucket after the upload has been done.- The type of this property is the same as if you were using the Firebase Storage SDK directly with
firebase.storage().bucket(bucketname)
- The type of this property is the same as if you were using the Firebase Storage SDK directly with
isPublic: If the file is public or private.publicUrl: If the file is public, the public URL will be returned.
Using your own Firebase instance
You can pass an optional parameter to the FirebaseStorage constructor to use your own Firebase instance. In this case, the credentials and bucket options will be ignored.
const Express = require('express')
const Multer = require('multer')
const fbAdmin = require('firebase-admin')
const FirebaseStorage = require('multer-firebase-storage')
const app = new Express()
const fbInstance = fbAdmin.initializeApp({
credential: fbAdmin.credential.cert(somecredentials),
storageBucket: 'some bucket'
})
const multer = Multer({
storage: FirebaseStorage({}, fbInstance)
})
app.post('/file', multer.single('file'), (req, res) => {
res.status(201).json(req.file)
})
app.listen(3000, () => {
console.log('Example app listening on port 3000!')
})Lifecycle hooks
Multer-Firebase-Storage supports the following lifecycle hooks:
beforeUpload: This hook will be called before the file is uploaded to Firebase Storage.afterUpload: This hook will be called after the file is uploaded to Firebase Storage.beforeDelete: This hook will be called before the file is deleted from Firebase Storage.afterDelete: This hook will be called after the file is deleted from Firebase Storage.beforeInit: This hook will be called before the Firebase Storage instance is initialized.afterInit: This hook will be called after the Firebase Storage instance is initialized.
Each hook has a different function signature:
beforeUpload:(req, file) => voidreqis the Express request object.fileis the Multer file object.
afterUpload:(req, file, fileRef, bucketRef) => voidreqis the Express request object.fileis the Multer file object.fileRefandbucketRefare the references to the Firebase Storage objects.
beforeDelete:(req, file) => voidreqis the Express request object.fileis the Multer file object.
afterDelete:(req, file, fileRef, bucketRef) => voidreqis the Express request object.fileis the Multer file object.fileRefandbucketRefare the references to the Firebase Storage objects.
beforeInit:(storageInstance) => voidstorageInstanceis the Firebase Storage instance passed asthis.
afterInit:(storageInstance, firebaseInstance) => voidstorageInstanceis the Firebase Storage instance passed asthis.firebaseInstanceis the Firebase instance passed either as the second parameter to theFirebaseStorageconstructor or the internally constructed instance.
Usage example
const Express = require('express')
const Multer = require('multer')
const FirebaseStorage = require('multer-firebase-storage')
const app = new Express()
const multer = Multer({
storage: FirebaseStorage({
bucketName: 'your-default-bucket',
credentials: {
clientEmail: 'your-firebase-client-email',
privateKey: 'your private key',
projectId: 'your-project-id'
},
hooks: {
beforeInit (instance) {
console.log(`before init:`, instance)
},
afterInit (instance, fb) {
console.log(`after init:`, instance, fb)
},
beforeUpload (req, file) {
console.log(`before upload:`, req, file)
},
afterUpload (req, file, fref, bref) {
console.log(`after upload:`, req, file, fref, bref)
},
beforeRemove (req, file) {
console.log(`before remove:`, req, file)
},
afterRemove (req, file, fref, bref) {
console.log(`after remove:`, req, file, fref, bref)
}
}
})
})
app.post('/file', multer.single('file'), (req, res) => {
res.status(201).json(req.file)
})
app.listen(3000, () => {
console.log('Example app listening on port 3000!')
})