npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

multer-firebase-sharp

v1.0.0

Published

Multer Storage Engine for Firebase Storage along with integration with npm sharp library for image manipulation before upload

Downloads

2

Readme

multer-firebase-storage-sharp

Multer Storage Engine for Firebase With npm sharp integration for image processing

Inspired by Lucas Santos' multer-firebase-storage

Installation

npm install multer-firebase-storage-sharp

Usage

Using Express:

const Express = require('express')
const Multer = require('multer')
const FirebaseStorage = require('multer-firebase-storage-sharp')
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
    }
    sharpPipeline: sharp.Sharp || null
}

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, clientEmail which can be obtained by the Firebase console.
    • Note: The privateKey field 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.jpg and the directory path is images, the resulting file name will be images/image.jpg. There's no need to add a trailing slash.
  • 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 application

  • namePrefix: 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.jpg and the prefix is preview_, the resulting file name will be preview_image.jpg.
  • 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.jpg and the suffix is _final, the resulting file name will be image_final.jpg.
  • unique: If set to true, the file name will be unique by generating a time-based hash that will be appended to the end of the file name (after nameSuffix and before the file extension). If set to false, the file name will be the same as the original file name.

    • For example: if the file name is image.jpg and the suffix is _final and unique is true, the resulting file name will be image_final<somehashhere>.jpg.
  • public: If set to true, the file will be made public and the public URL will be returned. If set to false, the file will be private.

  • hooks: Where you can define lifecycle hooks

  • sharpPipeline: When using this storage engine for images, you can create a full image processing pipeline using the npm sharp library before the actual file gets uploaded to firebase. Usage Eg.

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)
  • 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-sharp')
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) => void
    • req is the Express request object. file is the Multer file object.
  • afterUpload: (req, file, fileRef, bucketRef) => void
    • req is the Express request object. file is the Multer file object. fileRef and bucketRef are the references to the Firebase Storage objects.
  • beforeDelete: (req, file) => void
    • req is the Express request object. file is the Multer file object.
  • afterDelete: (req, file, fileRef, bucketRef) => void
    • req is the Express request object. file is the Multer file object. fileRef and bucketRef are the references to the Firebase Storage objects.
  • beforeInit: (storageInstance) => void
    • storageInstance is the Firebase Storage instance passed as this.
  • afterInit: (storageInstance, firebaseInstance) => void
    • storageInstance is the Firebase Storage instance passed as this. firebaseInstance is the Firebase instance passed either as the second parameter to the FirebaseStorage constructor or the internally constructed instance.

Usage example

const Express = require('express')
const Multer = require('multer')
const FirebaseStorage = require('multer-firebase-storage-sharp')
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!')
})

Sharp Example

const Express = require('express')
const Multer = require('multer')
const FirebaseStorage = require('multer-firebase-storage-sharp')
const sharp = require('sharp')
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'
    },
    sharpPipeline: sharp().rotate(180).resize({ width: 100, height: 100 }).blur()
  })
})