Reputation: 31
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
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