Can't resolve getSignedUrl Promise in Cloud Function

ぃ、小莉子 提交于 2021-01-29 05:25:54

问题


I have been trying to debug a Google Cloud Function that should return a signedUrl for uploading a file to Google Cloud Storage.

I have an https cloud function:

exports.gcpSecureURL = functions.https.onCall((data, res) => {

    const bucketName = data.bucket;
    const fileName = data.filename;

    let signedUrl = generateV4UploadSignedUrl(bucketName, fileName)
        .then(value => {
            console.log("VALUE: ", value);
            return value
        })

    res.send(signedUrl) 
        
});

Value is never reached and signedUrl is always a Promise.

In the generateV4UploadSignedUrl function I have:

async function generateV4UploadSignedUrl(bucketName, fileName) {
    // These options will allow temporary uploading of the file with outgoing
    // Content-Type: application/octet-stream header.
    const options = {
      version: 'v4',
      action: 'write',
      expires: Date.now() + 15 * 60 * 1000, // 15 minutes
      contentType: 'application/octet-stream',
    };
  
    // Get a v4 signed URL for uploading file
    const [url] = await storage
      .bucket(bucketName)
      .file(fileName)
      .getSignedUrl(options)
      
    return url;
  };

The param bucketName is correct and fileName is just the name of the file I want to upload so at the stage where I generate the url should not matter?

I don't get why the signedUrl() method is not returning anything at all. I changed the permission on my bucket to StorageAdmin for AllUsers and my function is set to allow unauthenticated.

There is a TypeError in generateV4UploadSignedUrl in the cloud function logs:

TypeError: (intermediate value) is not iterable
at generateV4UploadSignedUrl (/workspace/index.js:51:19)

I have no idea what is happening and the function logs seem pretty opaque. What am I doing wrong please?


回答1:


You have two problems here.

First, you're using a callable type function, but you appear to be using it as if you are writing an HTTP function. If you want to write a callable function, please be sure to review the documentation for that. They work differently than HTTP functions. With callable functions, you must return a promise with the data to send to the caller. With HTTP functions, you invoke res.send() or equivalent to send a response after all the async work is complete. Be sure you understand the difference between the two.

Value is never reached and signedUrl is always a Promise.

signedUrl is always a promise because generateV4UploadSignedUrl is async, and all async functions always return a promise. You will have to await the promise to get the resolved value from the promise.

Your function should use async/await, and look more like this:

exports.gcpSecureURL = functions.https.onCall(async (data, context) => {

    const bucketName = data.bucket;
    const fileName = data.filename;

    let signedUrl = await generateV4UploadSignedUrl(bucketName, fileName)
    console.log("VALUE: ", signedUrl);
    return signedUrl
        
});

While this might not do exactly what you want (be sure that the entire contents of signedUrl is what you want to send to the client), it should get you closer to what you want.



来源:https://stackoverflow.com/questions/62817559/cant-resolve-getsignedurl-promise-in-cloud-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!