skip to Main Content

I need to download html pages only for authenticated users, pages are stored in "Firebase Storage" as html.

I get the right action by using the bellow firebase cloud function (v2) (getReportForUser) using getDownloadURL() (commented-out) , the problem is that users can share files, which I want to avoid, so I switched to use getSignedURL() that will give the user a limited time to download the file, but I got Error: Permission 'iam.serviceAccounts.signBlob' denied on resource (or it may not exist).

Is this the right approach to authenticate downloading files, and is yes, how can we resolve this error please?

exports.getReportForUser = onCall({ region: ["europe-west1"] }, async (request) => {

    const getReportURLsync = () => {
        return new Promise(async (resolve) => {
            // Get a reference to index.html file in storage bucket
            const fileRef = getStorage().bucket("wa-connect").file("reports/" + "index.html");
            resolve(await fileRef.getSignedUrl({version: "v4", action: "read", expires: Date.now() + 1000 * 60 * 2, })); // expires in 2 minutes
            //resolve( await getDownloadURL(fileRef));

        }
    )}
    
    async function getReportURL(serial, timestamp) {
        return await getReportURLsync(serial, timestamp);
    }

    try {
        return { reportURL: await getReportURL() };
    } catch (err) {
        info("Error caught in getReportForUser code: ", "->", err);
    }
});

I also tried the accepted answer in Permissions Denied on getSignedUrl Promise in Cloud Function but it didn’t work!

2

Answers


  1. Chosen as BEST ANSWER

    I solved the issue by getting the contents of the report and inserting it into the client report page, this way only authenticated users can see the report.

    I get the contents using the same function above (getReportForUser) with a slight modification so that it returns the contents instead of the report URL.


  2. Both a download URL and a signed URL give public access to the file, which is not what you want.

    Instead you’ll want to use the SDK to download the data with its getBlob, getBytes and getStream method. These methods all give authorized users access to the data in the file, without using a public URL.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search