简体   繁体   中英

Firebase Cloud Function Serving Local File for Download

I created cloud function that generates an xlsx file, I need the user to download that file after it's generated.

Method 1: Upload to Bucket, then redirect

So far i've tried uploading the file to a bucket using this API , and then redirect him to the bucket file url, I also double checked the bucket name using this API , but I get the same error every time:

{"error":{"code":500,"status":"INTERNAL","message":"function crashed","errors":["socket hang up"]}}

Portion of the code that contains uploading to bucket:

    const { Storage } = require('@google-cloud/storage');
    const storage = new Storage();
    await storage.bucket('bucket-name').upload('myfile.xlsx', {
        gzip: false,
    });

Portion of the code that proves file exists:

    fs.access('myfile.xlsx', fs.constants.F_OK, (err) => {
        console.log(`${file} ${err ? 'does not exist' : 'exists'}`);
    });

I also checked if the library "@google-cloud/storage" reads the file, and it reads it correctly and gets the file size right.

Method 2: Direct Download

Download the file directly, the problem is that every doc online for nodejs to download a local file to the user is setting up a custom server to download the file, but i'm using firebase, so it's not in control of that server.

If your excel file is created and should be returned to the client as a response to an HTTP request (calling to an API endpoint) then this is how you can do it.

export const getExcelFile = functions.https.onRequest(async (request, response) => {
    // ...
    // Create your file and such
    // ..

    await storage.bucket('bucket-name').upload('myfile.xlsx', {
        gzip: false,
    });

    response.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    response.send(fs.readFileSync('myfile.xlsx'));
    return null;
});

Otherwise, if the excel file is created as a response to an event, and you want the user to download the file at another time, then you create a download link and serve it to the user in any way you want.

// ...
// Create your file and such
// ..


const [file] = await storage.bucket('bucket-name').upload('myfile.xlsx', {
    gzip: false,
});
const [downloadUrl] = await file.getSignedUrl({ 
  action: 'read',
  expires: '20-03-2019' // Link expiry date: DD-MM-YYYY
});

console.log(downloadUrl);

Just wanted to add more detail to the answer, since there's no need to write into a file and read from it to download it's data, simply take the data and send it, using the few lines below.

    res.setHeader('Content-Type', 'application/vnd.openxmlformats');
    res.setHeader("Content-Disposition", "attachment; filename=" + fileName);
    res.end(fileData, 'binary');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM