3
votes

Hello I am trying to upload an image using Node.js/multer to firebase storage (note: I know I can do it client side but this needs to work server side). I am running into this issue:

TypeError: storage.ref is not a function

I tried solving by adding import 'firebase/storage'; as other Stack Overflows have suggested but that did not work.

Router:

import {FirebaseManager, FirebaseReferences} from '../database_manager';

router.post("/:uuid/image", upload.single("file"), (req, res) => {
    const tempPath = req.file.path;
    const ext = path.extname(req.file.originalname).toLowerCase();

    if (ext === ".png" || ext === ".jpg") {
        FirebaseManager.upload_image(FirebaseReferences.Images, 'test', req.file)
        res.status(200).contentType("text/plain").end("File uploaded!");
    } else {
        try {
            fs.unlinkSync(tempPath);
        } catch (err) {
            res.status(400).send(err.message);
        }
        res.status(403).contentType("text/plain").end("Only .png/jpg files are allowed!");
    }
  }
);

Firebase Manager:

var admin = require('firebase-admin');
import firebase = require('firebase/app');
import 'firebase/database';
import 'firebase/storage';

// Access the real-time database in the initialized application.
const FirebaseApp: firebase.app.App = admin.initializeApp({
  credential: admin.credential.cert({
    projectId: '',
    clientEmail: '',
    privateKey: ''
  }),
  databaseURL: 'https://.firebaseio.com'
});
const db: firebase.database.Database = FirebaseApp.database();
const storage: firebase.storage.Storage = FirebaseApp.storage();

export function upload_image(ref: FirebaseReferences, filename: string,
        file: any): string {

        var upload_loc = ref.toString() + '/' + filename;
        var upload_ref = storage.ref().child(upload_loc);

        upload_ref.put(file).then(function(snapshot) {
            snapshot.ref.getDownloadURL().then(function(downloadURL) {
                console.log('File available at', downloadURL);
                return downloadURL;
            });
        }, function(error) {
            console.log("FirebaseManager, upload_image(): " + error);
            throw error;
        });

        return 'error';
}

Also will uploading a Express.Multer.File type to Storage work? If not how can I convert that type to a type of File?

node 10.2.1
multer 1.4.1
firebase ^5.7.3
firebase-admin ^6.5.0
1
Looks like it can't find ref on your storage object in your upload_image function. I'm not entirely certain if you need to call bucket first. Additionally, I've experienced some issues in the past with express and code defined outside of exported functions. Could you, instead of calling storage.ref() in your upload_image function try calling admin.storage().bucket().ref() instead? - Carlo Field

1 Answers

5
votes

You are missing storageBucket in the config for admin.initializeApp

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    storageBucket: "<BUCKET_NAME>.appspot.com"
});

https://firebase.google.com/docs/storage/admin/start