You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Firestore写入文档?Cloud Functions签名URL无效果求助

Fixing Your Cloud Functions: Generate GCS Signed URLs & Write to Firestore

Hey there! As someone who's fumbled through GCP basics before, I totally get how frustrating it is when a function deploys but does absolutely nothing. Let's break down what's wrong with your code and get it working properly.

First, Let's Call Out the Critical Issues in Your Current Code

  • Undefined & misnamed variables: You’re using files in bucket.file(files) but never defined what files refers to—so your function can’t target any specific GCS file. Also, in the .then() block, you reference data[0] but the parameter is actually named signedUrls—that typo breaks the entire URL extraction step.
  • No trigger configured: Cloud Functions don’t run on their own—they need a trigger (like a file upload to GCS, an HTTP request, or a schedule). Your code just defines a function but doesn’t set up any way to kick it off.
  • Missing Firestore write logic: Your end goal is to save the URL to Firestore, but there’s zero code that connects to Firestore or writes data there.
  • Unnecessary key file: When running in Cloud Functions, you don’t need to specify keyFilename—the function automatically uses the associated service account identity. Using a local key file will break once deployed.

Let's Rewrite the Function (Example with GCS Trigger)

If you want to automatically generate a signed URL every time a file is uploaded to your GCS bucket and save it to Firestore, here’s a corrected version:

const { Storage } = require('@google-cloud/storage');
const { Firestore } = require('@google-cloud/firestore');

// Initialize clients without key files (uses Cloud Functions service account)
const storage = new Storage();
const firestore = new Firestore();

// Trigger: Runs when a file is added to your GCS bucket
exports.generateAndSaveSignedUrl = async (event) => {
  const file = event;
  const bucketName = file.bucket;
  const fileName = file.name;

  // Skip folder entries (common in GCS)
  if (fileName.endsWith('/')) {
    console.log('Skipping folder:', fileName);
    return;
  }

  try {
    // Generate signed URL
    const [signedUrl] = await storage.bucket(bucketName).file(fileName).getSignedUrl({
      action: 'read',
      expires: '03-09-2491' // Far-future expiration
    });

    console.log('Generated signed URL:', signedUrl);

    // Write URL to Firestore (adjust collection/document path to your needs)
    await firestore.collection('gcs_file_urls').doc(fileName).set({
      file_name: fileName,
      signed_url: signedUrl,
      created_at: Firestore.FieldValue.serverTimestamp()
    });

    console.log('Successfully saved URL to Firestore');
  } catch (error) {
    console.error('Error processing file:', error);
  }
};

If You Prefer an HTTP Trigger (Manual Invocation)

If you want to call the function manually to process specific files, use this version:

const { Storage } = require('@google-cloud/storage');
const { Firestore } = require('@google-cloud/firestore');

const storage = new Storage();
const firestore = new Firestore();
const BUCKET_NAME = 'modulus-1464f'; // Your bucket name

exports.getAndSaveSignedUrl = async (req, res) => {
  const fileName = req.query.fileName; // Pass file name via query param, e.g., ?fileName=my-document.pdf

  if (!fileName) {
    return res.status(400).send('Please add a fileName query parameter (e.g., ?fileName=your-file.txt)');
  }

  try {
    const [signedUrl] = await storage.bucket(BUCKET_NAME).file(fileName).getSignedUrl({
      action: 'read',
      expires: '03-09-2491'
    });

    await firestore.collection('gcs_file_urls').doc(fileName).set({
      file_name: fileName,
      signed_url: signedUrl,
      updated_at: Firestore.FieldValue.serverTimestamp()
    });

    res.status(200).json({
      message: 'URL saved to Firestore',
      signed_url: signedUrl
    });
  } catch (error) {
    console.error('Error:', error);
    res.status(500).send('Failed to generate or save the URL');
  }
};

Next Steps to Make It Work

  1. Set up permissions:
    • Go to the IAM section in GCP Console, find your Cloud Functions service account (it looks like PROJECT_ID@appspot.gserviceaccount.com).
    • Add these roles:
      • Storage Object Viewer (to access GCS files and generate signed URLs)
      • Cloud Datastore User (to write to Firestore)
  2. Deploy the function:
    • For the GCS trigger: Run gcloud functions deploy generateAndSaveSignedUrl --trigger-resource modulus-1464f --trigger-event google.storage.object.finalize
    • For the HTTP trigger: Run gcloud functions deploy getAndSaveSignedUrl --runtime nodejs20 --trigger-http (adjust the Node.js runtime to your preferred version)
  3. Test it:
    • For GCS trigger: Upload a file to your bucket and check Firestore for the new document.
    • For HTTP trigger: Call the function URL with ?fileName=your-file-name and verify the response + Firestore entry.

内容的提问来源于stack exchange,提问作者Shubham Jain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 07:42:33