如何在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
filesinbucket.file(files)but never defined whatfilesrefers to—so your function can’t target any specific GCS file. Also, in the.then()block, you referencedata[0]but the parameter is actually namedsignedUrls—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
- 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)
- Go to the IAM section in GCP Console, find your Cloud Functions service account (it looks like
- 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)
- For the GCS trigger: Run
- 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-nameand verify the response + Firestore entry.
内容的提问来源于stack exchange,提问作者Shubham Jain
相关产品推荐
相关产品推荐

