Firebase Storage with Google Actions

Viewed 163

I am having some issues connecting my firebase storage with my google action. I need to be able to "download" the json files inside in order to be able to read and pick out what a user may need given data that they provide when they call the action.

Below is the code that I currently have, complied from the different APIs and other stackoverflow questions I have found.

const functions = require('firebase-functions');
const admin = require('firebase-admin');
const Firestore = require('@google-cloud/firestore');
const firestore = new Firestore();

var storage = require('@google-cloud/storage');
const gcs = storage({projectId: 'aur-healthcare-group'});
const bucket = gcs.bucket('gs://aur-healthcare-group');


admin.storage().bucket().file('aur-healthcare-group/aur_members.json').download(function(errr, contents){
  if(!err){
    var jsObjext = JSON.parse(contents.toString('utf8'));
  }
});

The current error I am receiving is "code":3,"message":"Function failed on loading user code. This is likely due to a bug in the user code. Error message: Error: please examine your function logs to see the error cause. When I check the logs I only get the above mentioned message again.

I believe that I am not accessing my firebase storage correctly and have trouble finding a good resource on how to access this correctly. Would somebody be able to give me an example of how to access the storage correctly so I will be able to apply it to my project?

1 Answers

Since you're running in Firebase Functions, you shouldn't need to require the @google-cloud/storage dependency directly. Rather, you can get the correctly authenticated storage component via admin.storage()

Following that, you shouldn't download the file to your function, as you would be better off reading directly into memory via a readStream.

With regards to your existing code error, it may be because you're checking if (!err) when the callback variable is errr.

I've done this in the past and here's a code snippet of how I achieved it. It's written in Typescript specifically, but I think you should be able to port it to JS if you're using that directly.

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin'
import { Bucket } from '@google-cloud/storage';

admin.initializeApp()

const db = admin.firestore()

const bucket = admin.storage().bucket('project-id.appspot.com') // Use your project-id here.

const readFile = async (bucket: Bucket, fileName: string) => {
  const stream = bucket.file(fileName).createReadStream();
  return new Promise((resolve, reject) => {
    let buffer = '';
    stream.on('data', function(d: string) {
      buffer += d;
    }).on('end', function() {
      resolve(buffer)
    });
  })
}

app.handle('my-intent-handler', async (conv) => {
  const contents = await readArticle(bucket, 'filename.txt')
  conv.add(`Your content is ${contents}`)
})

exports.fulfillment = functions.https.onRequest(app)
Related