William Wu
William Wu

Reputation: 483

database triggers firebase function to download images from URL and save it to storage

I want to download the image and save it to storage when my database is updated with the 'photo_url' field

exports.saveToStorage = functions.database.ref(`/images/${itemImageRef}`)
.onWrite(event => {
  const filePath = event.data.val();
  const filename = filePath.split('/').pop();

  var download = request.get(filePath).on('error', (err) => {
    console.log(err)
  })
  .pipe(fs.createWriteStream(filename));

  download.on('finish', () => {
    const bucket = gcs.bucket('id.appspot.com');
    const storagePath = `images/${filename}`;

    return bucket.upload(download, { destination: storagePath })
    .then(() => {
      console.log('success upload');
    });
  });
});

it logs "Error: EROFS: read-only file system, open 'image.jpg' at Error (native)." I suppose I cannot retrieve the file saved by createWriteStream? So how should I download images from the web?

Upvotes: 2

Views: 2802

Answers (1)

William Wu
William Wu

Reputation: 483

with the post suggested by @Jobsamuel, the code now works:

exports.saveToStorage = functions.database.ref(`/images/${itemImageRef}`)
.onWrite(event => {

  const filePath = event.data.val();
  const filename = filePath.split('/').pop();

  const bucket = gcs.bucket('id.appspot.com');
  const remoteWriteStream = bucket.file(filename).createWriteStream({
    metadata: { contentType: 'image/jpeg' }
  });

  request(filePath).pipe(remoteWriteStream)
  .on('error', (err) => console.log(err))
  .on('finish', () => console.log('success save image'));

});

By pipe the request result directly to the bucket, it solves the problem by skipping the step writing to a local file, which I suspect is the reason my original code fails. Also, don't forget to set contentType for images.

Upvotes: 4

Related Questions