4
votes

I'm trying to send a response back to a client using an http trigger from firebase cloud functions. When I sent the response using the file location from Cloud Storage, the sendFile method throws this error:

"path must be absolute or specify root to res.sendFile"

res.sendFile(obj.path(param1, param2, param3, param4));

obj.path(param1, param2, param3, param4) this builds a path to gs:// or an https:// with the params.

Then I decided to do this:

const rp = require("request-promise");

exports.fun = functions.https.onRequest( async (req, res) => {
let extResponse = await rp('firebase storage location');
          extResponse.pipe(res);
});

rp is now returning this error:

StatusCodeError: 403 - "{\n  \"error\": {\n    \"code\": 403,\n    \"message\": \"Permission denied. Could not perform this operation\"\n  }\n}"

This error is because cloud storage requires the request to be authenticated in order to let the service download the file from storage.

Is there a way to make this work and return the file back to the client?

1

1 Answers

9
votes

sendFile won't work, because it doesn't understand URLs. It only understand files on the local filesystem. You should be using the Cloud Storage SDK for node to do this. Create a File object that points to the file you want to send, open up a read stream on it, then pipe the stream to the response:

const file = ... // whatever file you want to send
const readStream = file.createReadStream()
readStream.pipe(res)