Firebase云函数 – 将文件对象上传到云存储

huangapple go评论51阅读模式
英文:

Firebase Cloud Functions - Upload a File object to Cloud Storage

问题

exports.getPdfUrl = functions.https.onRequest(async (req, res) => {
    const bucket = admin
        .storage()
        .bucket();
    // 目标文件名
    const file = bucket
        .file('test.pdf');

    // 创建 PDF 文件
    await new Promise<void>((resolve, reject) => {
        let stream = file.createWriteStream({
            resumable: false,
            contentType: "application/pdf",
        });
        stream.on("finish", () => resolve());
        stream.on("error", (e) => reject(e));
        const doc = new PDFDocument({ size: "A4", margin: 50 });
        doc.text("some text", 50, 50);
        doc.pipe(stream);
        doc.end();
    });
    ...
    const url = await file.getSignedUrl({
        version: "v4",
        action: "read",
        expires: Date.now() + 7 * 24 * 60 * 60 * 1000,
    });
    const [uploadedFile] = await bucket.upload('test.pdf', {
        destination: 'testNew.pdf',
        metadata: {
            contentType: 'application/pdf'
        }
    });
    await uploadedFile.makePublic();
    const publicUrl = `https://storage.googleapis.com/${bucket.name}/${encodeURIComponent('testNew.pdf')}`;
英文:

In my function I create a pdf file using the pdfkit library:

exports.getPdfUrl = functions.https.onRequest(async (req, res) =&gt; {
    const bucket = admin
        .storage()
        .bucket();
    //target file name
    const file = bucket
        .file(&#39;test.pdf&#39;);

    //creating the pdf file
    await new Promise&lt;void&gt;((resolve, reject) =&gt; {
        let stream = file.createWriteStream({
            resumable: false,
            contentType: &quot;application/pdf&quot;,
        });
        stream.on(&quot;finish&quot;, () =&gt; resolve());
        stream.on(&quot;error&quot;, (e) =&gt; reject(e));
        const doc = new PDFDocument({ size: &quot;A4&quot;, margin: 50 });
        doc.text(&quot;some text&quot;, 50, 50);
        doc.pipe(stream);
        doc.end();
    });
    ...

This works so far and creates a proper pdf file.

Now I want to upload the created file to storage and return a url.

I can't to this, because the getSignedUrl expires maximum is 7 days (I need a permanent url) :

    const url = await file.getSignedUrl({
        version: &quot;v4&quot;,
        action: &quot;read&quot;,
        expires: Date.now() + 7 * 24 * 60 * 60 * 1000,
    });

I can't do this, because the first argument of bucket.upload() is the path to the file, which I don't have, because I only have the File object:

    const [uploadedFile] = await bucket.upload(&#39;test.pdf&#39;, {
        destination: &#39;testNew.pdf&#39;,
        metadata: {
            contentType: &#39;application/pdf&#39;
        }
    });
    await uploadedFile.makePublic();
    const publicUrl = `https://storage.googleapis.com/${bucket.name}/${encodeURIComponent(&#39;testNew.pdf&#39;)}`;

答案1

得分: 1

const tmpFilePath = path.join(os.tmpdir(), fileName);
// 从 Cloud Storage 文件创建一个读取流
const readStream = file.createReadStream();

// 创建一个写入流到本地临时文件
const writeStream = fs.createWriteStream(tmpFilePath);

// 将读取流连接到写入流
readStream.pipe(writeStream);

// 在写入流上监听完成事件
await new Promise((resolve, reject) => {
    writeStream.on("finish", resolve);
    writeStream.on("error", reject);
});

这将在存储桶的主目录中创建文件。

然后可以将其保存到其他位置:

const [uploadedFile] = await bucket.upload(tmpFilePath, {
    destination: `someOtherPath/${fileName}`,
    metadata: {
        contentType: "application/pdf",
    },
});
await uploadedFile.makePublic();
const url = `https://storage.googleapis.com/${bucket.name}/${encodeURIComponent(`someOtherPath/${fileName}`)}`;
英文:
    const tmpFilePath = path.join(os.tmpdir(), fileName);
    // Create a read stream from the Cloud Storage file
    const readStream = file.createReadStream();

    // Create a write stream to the local temporary file
    const writeStream = fs.createWriteStream(tmpFilePath);

    // Pipe the read stream to the write stream
    readStream.pipe(writeStream);

    // Listen for the finish event on the write stream
    await new Promise((resolve, reject) =&gt; {
        writeStream.on(&quot;finish&quot;, resolve);
        writeStream.on(&quot;error&quot;, reject);
    });

This will create a the file in the main directory of the storage bucket.

From there it can be saved to other locations:

    const [uploadedFile] = await bucket.upload(tmpFilePath, {
        destination: `someOtherPath/${fileName}`,
        metadata: {
            contentType: &quot;application/pdf&quot;,
        },
    });
    await uploadedFile.makePublic();
    const url = `https://storage.googleapis.com/${bucket.name}/${encodeURIComponent(`someOtherPath/${fileName}`)}`;

huangapple
  • 本文由 发表于 2023年5月7日 23:21:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/76194771.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定