0

Situation

I have a firebase function that updates the user image.

Problem

When I run locally my function using firebase serve, I successfully upload the image to firestore using Postman. However, when I run firebase deploy and I try to upload the image using Postman, I get a 500 Internal Server Error. The other functions (not dealing with FormData, just json) work perfectly when I deploy them.

I don't understand why it works locally, but not on deploy when I am doing the exact same thing. Not sure if this is something in the config I am missing, or if I am doing something wrong. Any help would be appreciated!

Code users.js

const { admin, db, firebase } = require('../util/admin');
const config = require('../util/config');

exports.postUserImage = (req, res) => {
  const BusBoy = require('busboy');
  const path = require('path');
  const os = require('os');
  const fs = require('fs');

  let imgFileName;
  let imgToBeUploaded = {};
  const busboy = new BusBoy({ headers: req.headers });

  busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
    // Invalid file type
    if (mimetype !== 'image/jpeg' && mimetype !== 'image/png') {
      return res.status(400).json({ error: 'Invalid file type' });
    }
    // Extract img extension
    const imgDotLength = filename.split('.').length;
    const imgExtension = filename.split('.')[imgDotLength - 1];
    // Create img file name
    imgFileName = `${Math.round(Math.random() * 1000000)}.${imgExtension}`;
    // Create img path
    const filepath = path.join(os.tmpdir(), imgFileName);
    // Create img object to be uploaded
    imgToBeUploaded = { filepath, mimetype };
    // Use file system to create the file
    file.pipe(fs.createWriteStream(filepath));
  });
  busboy.on('finish', () => {
    admin
      .storage()
      .bucket()
      .upload(imgToBeUploaded.filepath, {
        resumable: false,
        metadata: {
          metadata: {
            contentType: imgToBeUploaded.mimetype
          }
        }
      })
      .then(() => {
        // Create img url to add to our user
        const imgUrl = `https://firebasestorage.googleapis.com/v0/b/${config.storageBucket}/o/${imgFileName}?alt=media`;
        // Add img url to user document
        return db.doc(`/users/${req.user.handle}`).update({ imgUrl });
      })
      .then(() => {
        return res.json({ message: 'Image uploaded succesfully' });
      })
      .catch((err) => {
        console.error(err);
        return res.status(500).json({ error });
      });
  });
  busboy.end(req.rawBody);
};

index.js

const { app, functions } = require('./util/admin');
const FirebaseAuth = require('./util/firebaseAuth');
const {
  postUserImage,
} = require('./handlers/users');
app.post('/user/image', FirebaseAuth, postUserImage);
EPaz
  • 85
  • 1
  • 2
  • 13
  • According to [SO post](https://stackoverflow.com/questions/55959624/saving-image-to-cloud-firestore) "You don’t save image into firestore but image url. After you save image into Google Cloud Storage you have to get the url of that image and then save the url to firestore. " – marian.vladoi Jul 16 '20 at 08:13
  • I believe that is what I am doing with busboy by creating the img url to add to the user – EPaz Jul 16 '20 at 17:00
  • I think it might be an issue with `const filepath = path.join(os.tmpdir(), imgFileName)`. The temp directory on your local machine is not the same as the temp directory on cloud functions. – marian.vladoi Jul 23 '20 at 13:45

0 Answers0