Only one Circle
Only one Circle

Reputation: 31

Firebase Storage public URL Access Denied ( I need a permanent URL with public access ) makePublic()

if mishandling When Access token revoked GetdownloadURL() will invalid. Hence I need a public access permanent URL without access token. How to makePublic() something did mistake but I can't conclude, gcs.bucket("Project-12345.appspot.com").file(fileName).makePublic()

Security Rules

service firebase.storage {
    match /b/{bucket}/o { 
    match /{allPaths=**} {
    allow read;
    allow write: if request.auth != null;
    }}}

Mycode

    const functions = require('firebase-functions');
    const admin = require('firebase-admin');
    const serviceAccount = require('./ProjectID-12345-firebase-adminsdk-.json');
    admin.initializeApp({
       credential: admin.credential.cert(serviceAccount),
       databaseURL: "https://ProjectID-12345.firebaseio.com"     
    });
    const {Storage} = require('@google-cloud/storage');
    const gcs = new Storage({
        projectId: "projectId-12345",
        keyFilename: serviceAccount
    });

    const GetUrl = (productId) => {
        const ImgList = ["ImgA_650x650", "ImgB_650x650", "ImgC_650x650", "ImgD_650x650"] ;
        let url = []
        ImgList.forEach( (element , Index) =>{
             let fileName = "product/"+ productId + "/resize"+ element;
             let storageref = gcs.bucket("Project-12345.appspot.com").file(fileName);
             storageref.makePublic();
             url[Index] = storageref.publicUrl();
        })
        return url;
     }

I get URL without Access token

[ 'https://storage.googleapis.com/Project-12345.appspot.com/product/1zHTmjNc5CV4WBLDLgdV/resizeImgA_650x650', 'https://storage.googleapis.com/Project-12345.appspot.com/product/1zHTmjNc5CV4WBLDLgdV/resizeImgB_650x650', 'https://storage.googleapis.com/Project-12345.appspot.com/product/1zHTmjNc5CV4WBLDLgdV/resizeImgC_650x650', 'https://storage.googleapis.com/Project-12345.appspot.com/product/1zHTmjNc5CV4WBLDLgdV/resizeImgD_650x650' ]

But the issue is the URL is access denied. it Show error as

This XML file does not appear to have any style information associated with it. The document tree is shown below.

<Error>
<Code>AccessDenied</Code>
<Message>Access denied.</Message>
<Details>Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object.</Details>
</Error>

Upvotes: 3

Views: 1531

Answers (1)

vitooh
vitooh

Reputation: 4272

The problem might be related with fact that makePublic() is asynchronous and in the presented code its use in synchronus way and as the results publicUrl(), which is synchronous, is executed before it.

makePublic() should be used with await in async function like:

const GetUrl = async (productId) => { 
...
   await storageref.makePublic();
...

or with then like:

storageref.makePublic().then(() => url[Index] = storageref.publicUrl());

or with callback.

Of course please treat is as pseudo code. I am not sure if you can just copy paste it and it will work, anyway for sure the function is asynchronous and have to be coded that way. There are nice examples in the documentation.

Upvotes: 1

Related Questions