Get Download URL from file uploaded with Cloud Functions for Firebase












47














After uploading a file in Firebase Storage with Functions for Firebase, I'd like to get the download url of the file.



I have this :



...

return bucket
.upload(fromFilePath, {destination: toFilePath})
.then((err, file) => {

// Get the download url of file

});


The object file has a lot of parameters. Even one named mediaLink. However, if I try to access this link, I get this error :




Anonymous users does not have storage.objects.get access to object ...




Can somebody tell me how to get the public download Url?



Thank you










share|improve this question
























  • See also this post which reconstructs the URL from data available in the function.
    – Kato
    Jun 14 '17 at 19:16
















47














After uploading a file in Firebase Storage with Functions for Firebase, I'd like to get the download url of the file.



I have this :



...

return bucket
.upload(fromFilePath, {destination: toFilePath})
.then((err, file) => {

// Get the download url of file

});


The object file has a lot of parameters. Even one named mediaLink. However, if I try to access this link, I get this error :




Anonymous users does not have storage.objects.get access to object ...




Can somebody tell me how to get the public download Url?



Thank you










share|improve this question
























  • See also this post which reconstructs the URL from data available in the function.
    – Kato
    Jun 14 '17 at 19:16














47












47








47


21





After uploading a file in Firebase Storage with Functions for Firebase, I'd like to get the download url of the file.



I have this :



...

return bucket
.upload(fromFilePath, {destination: toFilePath})
.then((err, file) => {

// Get the download url of file

});


The object file has a lot of parameters. Even one named mediaLink. However, if I try to access this link, I get this error :




Anonymous users does not have storage.objects.get access to object ...




Can somebody tell me how to get the public download Url?



Thank you










share|improve this question















After uploading a file in Firebase Storage with Functions for Firebase, I'd like to get the download url of the file.



I have this :



...

return bucket
.upload(fromFilePath, {destination: toFilePath})
.then((err, file) => {

// Get the download url of file

});


The object file has a lot of parameters. Even one named mediaLink. However, if I try to access this link, I get this error :




Anonymous users does not have storage.objects.get access to object ...




Can somebody tell me how to get the public download Url?



Thank you







node.js firebase firebase-storage google-cloud-functions






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 17 '18 at 10:13









Brian Burns

6,38234345




6,38234345










asked Mar 22 '17 at 15:35









Valentin

1,34131635




1,34131635












  • See also this post which reconstructs the URL from data available in the function.
    – Kato
    Jun 14 '17 at 19:16


















  • See also this post which reconstructs the URL from data available in the function.
    – Kato
    Jun 14 '17 at 19:16
















See also this post which reconstructs the URL from data available in the function.
– Kato
Jun 14 '17 at 19:16




See also this post which reconstructs the URL from data available in the function.
– Kato
Jun 14 '17 at 19:16












13 Answers
13






active

oldest

votes


















67














You'll need to generate a signed URL using getSignedURL via the @google-cloud/storage NPM module.



Example:



const gcs = require('@google-cloud/storage')({keyFilename: 'service-account.json'});
// ...
const bucket = gcs.bucket(bucket);
const file = bucket.file(fileName);
return file.getSignedUrl({
action: 'read',
expires: '03-09-2491'
}).then(signedUrls => {
// signedUrls[0] contains the file's public URL
});


You'll need to initialize @google-cloud/storage with your service account credentials as the application default credentials will not be sufficient.



UPDATE: The Cloud Storage SDK can now be accessed via the Firebase Admin SDK, which acts as a wrapper around @google-cloud/storage. The only way it will is if you either:




  1. Init the SDK with a special service account, typically through a second, non-default instance.

  2. Or, without a service account, by giving the default App Engine service account the "signBlob" permission.






share|improve this answer



















  • 22




    This is strange. We can easily get the Download Url from a Storage reference when using the Firebase Android, iOS and Web SDK. Why is it not as easy when being in admin? PS : Where can I find the 'service-account.json' needed to initialize gcs?
    – Valentin
    Mar 23 '17 at 8:26






  • 2




    This is because the admin-sdk does not have any Cloud Storage additions. You can get your admin-sdk service account json here console.firebase.google.com/project/_/settings/serviceaccounts/…
    – James Daniels
    Mar 23 '17 at 17:46






  • 1




    True, but none of the docs use getSignedUrl, something that I'll be fixing github.com/firebase/functions-samples/issues/82 According to Kato we do this in the codelab though.
    – James Daniels
    Apr 1 '17 at 2:21






  • 3




    URL generated with this method is ridiculously long. URL generated by @martemorfosis proposed method is much better. Is there any function that produce that URL? That's what I save in database for future use when I'm using firebase-sdk. A mirror method needs to exist in Functions domain.
    – Bogac
    Apr 19 '17 at 16:29






  • 2




    How can we upload the service-account.json along the deployed functions? I have tried placing it in the functions folder and referencing it in the file field in package.json but it is not getting deployed. Thank you.
    – José David Aroesti
    Apr 25 '17 at 18:20



















30














Here's an example on how to specify the download token on upload:



const UUID = require("uuid-v4");

const fbId = "<YOUR APP ID>";
const fbKeyFile = "./YOUR_AUTH_FIlE.json";
const gcs = require('@google-cloud/storage')({keyFilename: fbKeyFile});
const bucket = gcs.bucket(`${fbId}.appspot.com`);

var upload = (localFile, remoteFile) => {

let uuid = UUID();

return bucket.upload(localFile, {
destination: remoteFile,
uploadType: "media",
metadata: {
contentType: 'image/png',
metadata: {
firebaseStorageDownloadTokens: uuid
}
}
})
.then((data) => {

let file = data[0];

return Promise.resolve("https://firebasestorage.googleapis.com/v0/b/" + bucket.name + "/o/" + encodeURIComponent(file.name) + "?alt=media&token=" + uuid);
});
}


then call with



upload(localPath, remotePath).then( downloadURL => {
console.log(downloadURL);
});


The key thing here is that there is a metadata object nested within the metadata option property. Setting firebaseStorageDownloadTokens to a uuid-v4 value will tell Cloud Storage to use that as its public auth token.



Many thanks to @martemorfosis






share|improve this answer























  • This is the only solution that worked for me!
    – Ari
    Jun 13 '17 at 22:19










  • How do I get a valid UUID token for a file that is already uploaded on Storage? Generating random UUID did not help. Any pointers?
    – DerFaizio
    Jun 16 '17 at 8:14






  • 2




    Found the answer in @martemorfosis post. The UUID can be retrieved from the object.metadata exports.uploadProfilePic = functions.storage.object().onChange(event => { const object = event.data; // The Storage object. const uuid = object.metadata.firebaseStorageDownloadTokens; // ...
    – DerFaizio
    Jun 16 '17 at 10:02












  • You Saved the day ,only working solution for me.
    – Rishabh Chandel
    Jun 22 '17 at 15:28










  • Thank you for the bucket example! I was trying different combinations for the bucket and file methods for almost 1 hour :)
    – JCarlos
    Aug 29 '17 at 18:34



















11














With the recent changes in the functions object response you can get everything you need to "stitch" together the download URL like so:



 const img_url = 'https://firebasestorage.googleapis.com/v0/b/[YOUR BUCKET]/o/'
+ encodeURIComponent(object.name)
+ '?alt=media&token='
+ object.metadata.firebaseStorageDownloadTokens;

console.log('URL',img_url);





share|improve this answer





















  • thanks, it works for me
    – postace
    May 9 '18 at 11:49






  • 1




    This is the correct answer.
    – Uriel Frankel
    May 18 '18 at 13:21










  • Are you referring to the object response from bucket.file().upload()? I don't receive any metadata property in the response data, and I'm not sure how to get these firebaseStorageDownloadTokens.
    – Dygerati
    Jul 11 '18 at 20:30










  • also [YOUR BUCKET] is bucket.name, you don't have to hardcode it or use an extra local var
    – Călin Darie
    Jul 13 '18 at 7:28






  • 2




    The problem with this solution is that the service URL is hardcoded. If the Firebase/Google change it, it may break. Using the metadata.mediaLink property prevents such an issue.
    – Laurent
    Aug 2 '18 at 13:39



















10














One method I'm using with success is to set a UUID v4 value to a key named firebaseStorageDownloadTokens in the metadata of the file after it finishes uploading and then assemble the download URL myself following the structure Firebase uses to generate these URLs, eg:



https://firebasestorage.googleapis.com/v0/b/[BUCKET_NAME]/o/[FILE_PATH]?alt=media&token=[THE_TOKEN_YOU_CREATED]


I don't know how much "safe" is to use this method (given that Firebase could change how it generates the download URLs in the future ) but it is easy to implement.






share|improve this answer





















  • Do you have an example where you set the uuid value?
    – Drew Beaupre
    May 2 '17 at 3:32






  • 1




    I've the same question as Drew, where do you set the metadata? I tried to set while bucket.upload function, didn't work.
    – Vysakh Sreenivasan
    May 3 '17 at 11:47






  • 1




    Vysakh, I've posted a complete answer w/ example. Hope that helps you.
    – Drew Beaupre
    May 3 '17 at 15:47










  • Where/how do you create the token?
    – CodyBugstein
    Jul 20 '18 at 3:01










  • I would not consider this technique "safe", as download URLs are meant to be opaque, whose components are not to be broken down or assembled.
    – Doug Stevenson
    Sep 17 '18 at 4:49



















8














For those wondering where the Firebase Admin SDK serviceAccountKey.json file should go. Just place it in the functions folder and deploy as usual.



It still baffles me why we can't just get the download url from the metadata like we do in the Javascript SDK. Generating a url that will eventually expire and saving it in the database is not desirable.






share|improve this answer





















  • You can do it, just look at my answer.
    – Laurent
    Nov 16 '18 at 19:59



















8














I suggest using the option predefinedAcl: 'publicRead' when uploading a file with Cloud Storage NodeJS 1.6.x or +:



const options = {
destination: yourFileDestination,
predefinedAcl: 'publicRead'
};

bucket.upload(attachment, options);


Then, getting the public URL is as simple as:



bucket.upload(attachment, options).then(result => {
const file = result[0];
return file.getMetadata();
}).then(results => {
const metadata = results[0];
console.log('metadata=', metadata.mediaLink);
}).catch(error => {
console.error(error);
});





share|improve this answer























  • That does in fact appear to work. The only downside I see so far though is that if you hit the image in the URL bar of a browser, it will download the image instead of viewing it inline.
    – Michael Giovanni Pumo
    Nov 28 '18 at 15:14










  • file.getMetadata() did the trick for me after using the save() method on the file reference. Using it in NodeJS with firebase-admin sdk.
    – Pascal Lamers
    Dec 16 '18 at 23:34





















6














Sorry but i can't post a comment to your question above because of missing reputation, so I will include it in this answer.



Do as stated above by generating a signed Url, but instead of using the service-account.json I think you have to use the serviceAccountKey.json which you can generate at (replace YOURPROJECTID accordingly)



https://console.firebase.google.com/project/YOURPROJECTID/settings/serviceaccounts/adminsdk



Example:



const gcs = require('@google-cloud/storage')({keyFilename: 'serviceAccountKey.json'});
// ...
const bucket = gcs.bucket(bucket);
// ...
return bucket.upload(tempLocalFile, {
destination: filePath,
metadata: {
contentType: 'image/jpeg'
}
})
.then((data) => {
let file = data[0]
file.getSignedUrl({
action: 'read',
expires: '03-17-2025'
}, function(err, url) {
if (err) {
console.error(err);
return;
}

// handle url
})





share|improve this answer





























    3














    If you're working on a Firebase project, you can create signed URLs in a Cloud Function without including other libraries or downloading a credentials file. You just need to enable the IAM API and add a role to your existing service account (see below).



    Initialize the admin library and get a file reference as your normally would:



    import * as functions from 'firebase-functions'
    import * as admin from 'firebase-admin'

    admin.initializeApp(functions.config().firebase)

    const myFile = admin.storage().bucket().file('path/to/my/file')


    You then generate a signed URL with



    myFile.getSignedUrl({action: 'read', expires: someDateObj}).then(urls => {
    const signedUrl = urls[0]
    })


    Make sure your Firebase service account has sufficient permissions to run this




    1. Go to the Google API console and enable the IAM API (https://console.developers.google.com/apis/api/iam.googleapis.com/overview)

    2. Still in the API console, go to the main menu, "IAM & admin" -> "IAM"

    3. Click edit for the "App Engine default service account" role

    4. Click "Add another role", and add the one called "Service Account Token Creator"

    5. Save and wait a minute for the changes to propagate


    With a vanilla Firebase config, the first time you run the above code you'll get an error Identity and Access Management (IAM) API has not been used in project XXXXXX before or it is disabled.. If you follow the link in the error message and enable the IAM API, you'll get another error: Permission iam.serviceAccounts.signBlob is required to perform this operation on service account my-service-account. Adding the Token Creator role fixes this second permission issue.






    share|improve this answer





















    • I was just about to leave an answer with basically these same details that I FINALLY figured out the hard way - sure wish I had read through the solutions this far down earlier :/ This worked for me as of 12/12/18. Thanks for the detailed instructions, very helpful for us beginners!!
      – Kat
      Dec 12 '18 at 15:29



















    1














    This works if you just need a public file with a simple URL. Note that this may overrule your Firebase storage rules.



    bucket.upload(file, function(err, file) {
    if (!err) {
    //Make the file public
    file.acl.add({
    entity: 'allUsers',
    role: gcs.acl.READER_ROLE
    }, function(err, aclObject) {
    if (!err) {
    var URL = "https://storage.googleapis.com/[your bucket name]/" + file.id;
    console.log(URL);
    } else {
    console.log("Failed to set permissions: " + err);
    }
    });
    } else {
    console.log("Upload failed: " + err);
    }
    });





    share|improve this answer































      1














      I can't comment on the answer James Daniels gave, but I think this is very Important to read.



      Giving out a signed URL Like he did seems for many cases pretty bad and possible Dangerous.
      According to the documentation of Firebase the signed url expires after some time, so adding that to your databse will lead to a empty url after a certain timeframe



      It may be that misunderstood the Documentation there and the signed url doesn't expire, which would have some security issues as a result.
      The Key seems to be the same for every uploaded file. This means once you got the url of one file, someone could easily access files that he is not suposed to access, just by knowing their names.



      If i missunderstood that then i would lvoe to be corrected.
      Else someone should probably Update the above named solution.
      If i may be wrong there






      share|improve this answer





























        1














        For those who are using Firebase SDK andadmin.initializeApp:



        1 - Generate a Private Key and place in /functions folder.



        2 - Configure your code as follows:



        const serviceAccount = require('../../serviceAccountKey.json');
        try { admin.initializeApp(Object.assign(functions.config().firebase, { credential: admin.credential.cert(serviceAccount) })); } catch (e) {}


        Documentation



        The try/catch is because I'm using a index.js that imports other files and creates one function to each file. If you're using a single index.js file with all functions, you should be ok with admin.initializeApp(Object.assign(functions.config().firebase, { credential: admin.credential.cert(serviceAccount) }));.






        share|improve this answer





















        • for me it was '../serviceaccountkey.json' but thanks for the heads up to use the ../
          – robert king
          Nov 12 '18 at 12:34



















        1














        I had the same issue, however, I was looking at the code of the firebase function example instead of the README. And Answers on this thread didn't help either...



        You can avoid passing the config file by doing the following:




        Go to your project's Cloud Console > IAM & admin > IAM, Find the App
        Engine default service account and add the Service Account Token
        Creator role to that member. This will allow your app to create signed
        public URLs to the images.




        source: Automatically Generate Thumbnails function README



        Your role for app engine should look like this:



        Cloud Console






        share|improve this answer





























          0














          As of firebase 6.0.0 I was able to access the storage directly with the admin like this:



          const bucket = admin.storage().bucket();


          So I didn't need to add a service account. Then setting the UUID as referenced above worked for getting the firebase url.






          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f42956250%2fget-download-url-from-file-uploaded-with-cloud-functions-for-firebase%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            13 Answers
            13






            active

            oldest

            votes








            13 Answers
            13






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            67














            You'll need to generate a signed URL using getSignedURL via the @google-cloud/storage NPM module.



            Example:



            const gcs = require('@google-cloud/storage')({keyFilename: 'service-account.json'});
            // ...
            const bucket = gcs.bucket(bucket);
            const file = bucket.file(fileName);
            return file.getSignedUrl({
            action: 'read',
            expires: '03-09-2491'
            }).then(signedUrls => {
            // signedUrls[0] contains the file's public URL
            });


            You'll need to initialize @google-cloud/storage with your service account credentials as the application default credentials will not be sufficient.



            UPDATE: The Cloud Storage SDK can now be accessed via the Firebase Admin SDK, which acts as a wrapper around @google-cloud/storage. The only way it will is if you either:




            1. Init the SDK with a special service account, typically through a second, non-default instance.

            2. Or, without a service account, by giving the default App Engine service account the "signBlob" permission.






            share|improve this answer



















            • 22




              This is strange. We can easily get the Download Url from a Storage reference when using the Firebase Android, iOS and Web SDK. Why is it not as easy when being in admin? PS : Where can I find the 'service-account.json' needed to initialize gcs?
              – Valentin
              Mar 23 '17 at 8:26






            • 2




              This is because the admin-sdk does not have any Cloud Storage additions. You can get your admin-sdk service account json here console.firebase.google.com/project/_/settings/serviceaccounts/…
              – James Daniels
              Mar 23 '17 at 17:46






            • 1




              True, but none of the docs use getSignedUrl, something that I'll be fixing github.com/firebase/functions-samples/issues/82 According to Kato we do this in the codelab though.
              – James Daniels
              Apr 1 '17 at 2:21






            • 3




              URL generated with this method is ridiculously long. URL generated by @martemorfosis proposed method is much better. Is there any function that produce that URL? That's what I save in database for future use when I'm using firebase-sdk. A mirror method needs to exist in Functions domain.
              – Bogac
              Apr 19 '17 at 16:29






            • 2




              How can we upload the service-account.json along the deployed functions? I have tried placing it in the functions folder and referencing it in the file field in package.json but it is not getting deployed. Thank you.
              – José David Aroesti
              Apr 25 '17 at 18:20
















            67














            You'll need to generate a signed URL using getSignedURL via the @google-cloud/storage NPM module.



            Example:



            const gcs = require('@google-cloud/storage')({keyFilename: 'service-account.json'});
            // ...
            const bucket = gcs.bucket(bucket);
            const file = bucket.file(fileName);
            return file.getSignedUrl({
            action: 'read',
            expires: '03-09-2491'
            }).then(signedUrls => {
            // signedUrls[0] contains the file's public URL
            });


            You'll need to initialize @google-cloud/storage with your service account credentials as the application default credentials will not be sufficient.



            UPDATE: The Cloud Storage SDK can now be accessed via the Firebase Admin SDK, which acts as a wrapper around @google-cloud/storage. The only way it will is if you either:




            1. Init the SDK with a special service account, typically through a second, non-default instance.

            2. Or, without a service account, by giving the default App Engine service account the "signBlob" permission.






            share|improve this answer



















            • 22




              This is strange. We can easily get the Download Url from a Storage reference when using the Firebase Android, iOS and Web SDK. Why is it not as easy when being in admin? PS : Where can I find the 'service-account.json' needed to initialize gcs?
              – Valentin
              Mar 23 '17 at 8:26






            • 2




              This is because the admin-sdk does not have any Cloud Storage additions. You can get your admin-sdk service account json here console.firebase.google.com/project/_/settings/serviceaccounts/…
              – James Daniels
              Mar 23 '17 at 17:46






            • 1




              True, but none of the docs use getSignedUrl, something that I'll be fixing github.com/firebase/functions-samples/issues/82 According to Kato we do this in the codelab though.
              – James Daniels
              Apr 1 '17 at 2:21






            • 3




              URL generated with this method is ridiculously long. URL generated by @martemorfosis proposed method is much better. Is there any function that produce that URL? That's what I save in database for future use when I'm using firebase-sdk. A mirror method needs to exist in Functions domain.
              – Bogac
              Apr 19 '17 at 16:29






            • 2




              How can we upload the service-account.json along the deployed functions? I have tried placing it in the functions folder and referencing it in the file field in package.json but it is not getting deployed. Thank you.
              – José David Aroesti
              Apr 25 '17 at 18:20














            67












            67








            67






            You'll need to generate a signed URL using getSignedURL via the @google-cloud/storage NPM module.



            Example:



            const gcs = require('@google-cloud/storage')({keyFilename: 'service-account.json'});
            // ...
            const bucket = gcs.bucket(bucket);
            const file = bucket.file(fileName);
            return file.getSignedUrl({
            action: 'read',
            expires: '03-09-2491'
            }).then(signedUrls => {
            // signedUrls[0] contains the file's public URL
            });


            You'll need to initialize @google-cloud/storage with your service account credentials as the application default credentials will not be sufficient.



            UPDATE: The Cloud Storage SDK can now be accessed via the Firebase Admin SDK, which acts as a wrapper around @google-cloud/storage. The only way it will is if you either:




            1. Init the SDK with a special service account, typically through a second, non-default instance.

            2. Or, without a service account, by giving the default App Engine service account the "signBlob" permission.






            share|improve this answer














            You'll need to generate a signed URL using getSignedURL via the @google-cloud/storage NPM module.



            Example:



            const gcs = require('@google-cloud/storage')({keyFilename: 'service-account.json'});
            // ...
            const bucket = gcs.bucket(bucket);
            const file = bucket.file(fileName);
            return file.getSignedUrl({
            action: 'read',
            expires: '03-09-2491'
            }).then(signedUrls => {
            // signedUrls[0] contains the file's public URL
            });


            You'll need to initialize @google-cloud/storage with your service account credentials as the application default credentials will not be sufficient.



            UPDATE: The Cloud Storage SDK can now be accessed via the Firebase Admin SDK, which acts as a wrapper around @google-cloud/storage. The only way it will is if you either:




            1. Init the SDK with a special service account, typically through a second, non-default instance.

            2. Or, without a service account, by giving the default App Engine service account the "signBlob" permission.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 28 '18 at 13:50









            Doug Stevenson

            70.7k881101




            70.7k881101










            answered Mar 22 '17 at 17:53









            James Daniels

            4,35211723




            4,35211723








            • 22




              This is strange. We can easily get the Download Url from a Storage reference when using the Firebase Android, iOS and Web SDK. Why is it not as easy when being in admin? PS : Where can I find the 'service-account.json' needed to initialize gcs?
              – Valentin
              Mar 23 '17 at 8:26






            • 2




              This is because the admin-sdk does not have any Cloud Storage additions. You can get your admin-sdk service account json here console.firebase.google.com/project/_/settings/serviceaccounts/…
              – James Daniels
              Mar 23 '17 at 17:46






            • 1




              True, but none of the docs use getSignedUrl, something that I'll be fixing github.com/firebase/functions-samples/issues/82 According to Kato we do this in the codelab though.
              – James Daniels
              Apr 1 '17 at 2:21






            • 3




              URL generated with this method is ridiculously long. URL generated by @martemorfosis proposed method is much better. Is there any function that produce that URL? That's what I save in database for future use when I'm using firebase-sdk. A mirror method needs to exist in Functions domain.
              – Bogac
              Apr 19 '17 at 16:29






            • 2




              How can we upload the service-account.json along the deployed functions? I have tried placing it in the functions folder and referencing it in the file field in package.json but it is not getting deployed. Thank you.
              – José David Aroesti
              Apr 25 '17 at 18:20














            • 22




              This is strange. We can easily get the Download Url from a Storage reference when using the Firebase Android, iOS and Web SDK. Why is it not as easy when being in admin? PS : Where can I find the 'service-account.json' needed to initialize gcs?
              – Valentin
              Mar 23 '17 at 8:26






            • 2




              This is because the admin-sdk does not have any Cloud Storage additions. You can get your admin-sdk service account json here console.firebase.google.com/project/_/settings/serviceaccounts/…
              – James Daniels
              Mar 23 '17 at 17:46






            • 1




              True, but none of the docs use getSignedUrl, something that I'll be fixing github.com/firebase/functions-samples/issues/82 According to Kato we do this in the codelab though.
              – James Daniels
              Apr 1 '17 at 2:21






            • 3




              URL generated with this method is ridiculously long. URL generated by @martemorfosis proposed method is much better. Is there any function that produce that URL? That's what I save in database for future use when I'm using firebase-sdk. A mirror method needs to exist in Functions domain.
              – Bogac
              Apr 19 '17 at 16:29






            • 2




              How can we upload the service-account.json along the deployed functions? I have tried placing it in the functions folder and referencing it in the file field in package.json but it is not getting deployed. Thank you.
              – José David Aroesti
              Apr 25 '17 at 18:20








            22




            22




            This is strange. We can easily get the Download Url from a Storage reference when using the Firebase Android, iOS and Web SDK. Why is it not as easy when being in admin? PS : Where can I find the 'service-account.json' needed to initialize gcs?
            – Valentin
            Mar 23 '17 at 8:26




            This is strange. We can easily get the Download Url from a Storage reference when using the Firebase Android, iOS and Web SDK. Why is it not as easy when being in admin? PS : Where can I find the 'service-account.json' needed to initialize gcs?
            – Valentin
            Mar 23 '17 at 8:26




            2




            2




            This is because the admin-sdk does not have any Cloud Storage additions. You can get your admin-sdk service account json here console.firebase.google.com/project/_/settings/serviceaccounts/…
            – James Daniels
            Mar 23 '17 at 17:46




            This is because the admin-sdk does not have any Cloud Storage additions. You can get your admin-sdk service account json here console.firebase.google.com/project/_/settings/serviceaccounts/…
            – James Daniels
            Mar 23 '17 at 17:46




            1




            1




            True, but none of the docs use getSignedUrl, something that I'll be fixing github.com/firebase/functions-samples/issues/82 According to Kato we do this in the codelab though.
            – James Daniels
            Apr 1 '17 at 2:21




            True, but none of the docs use getSignedUrl, something that I'll be fixing github.com/firebase/functions-samples/issues/82 According to Kato we do this in the codelab though.
            – James Daniels
            Apr 1 '17 at 2:21




            3




            3




            URL generated with this method is ridiculously long. URL generated by @martemorfosis proposed method is much better. Is there any function that produce that URL? That's what I save in database for future use when I'm using firebase-sdk. A mirror method needs to exist in Functions domain.
            – Bogac
            Apr 19 '17 at 16:29




            URL generated with this method is ridiculously long. URL generated by @martemorfosis proposed method is much better. Is there any function that produce that URL? That's what I save in database for future use when I'm using firebase-sdk. A mirror method needs to exist in Functions domain.
            – Bogac
            Apr 19 '17 at 16:29




            2




            2




            How can we upload the service-account.json along the deployed functions? I have tried placing it in the functions folder and referencing it in the file field in package.json but it is not getting deployed. Thank you.
            – José David Aroesti
            Apr 25 '17 at 18:20




            How can we upload the service-account.json along the deployed functions? I have tried placing it in the functions folder and referencing it in the file field in package.json but it is not getting deployed. Thank you.
            – José David Aroesti
            Apr 25 '17 at 18:20













            30














            Here's an example on how to specify the download token on upload:



            const UUID = require("uuid-v4");

            const fbId = "<YOUR APP ID>";
            const fbKeyFile = "./YOUR_AUTH_FIlE.json";
            const gcs = require('@google-cloud/storage')({keyFilename: fbKeyFile});
            const bucket = gcs.bucket(`${fbId}.appspot.com`);

            var upload = (localFile, remoteFile) => {

            let uuid = UUID();

            return bucket.upload(localFile, {
            destination: remoteFile,
            uploadType: "media",
            metadata: {
            contentType: 'image/png',
            metadata: {
            firebaseStorageDownloadTokens: uuid
            }
            }
            })
            .then((data) => {

            let file = data[0];

            return Promise.resolve("https://firebasestorage.googleapis.com/v0/b/" + bucket.name + "/o/" + encodeURIComponent(file.name) + "?alt=media&token=" + uuid);
            });
            }


            then call with



            upload(localPath, remotePath).then( downloadURL => {
            console.log(downloadURL);
            });


            The key thing here is that there is a metadata object nested within the metadata option property. Setting firebaseStorageDownloadTokens to a uuid-v4 value will tell Cloud Storage to use that as its public auth token.



            Many thanks to @martemorfosis






            share|improve this answer























            • This is the only solution that worked for me!
              – Ari
              Jun 13 '17 at 22:19










            • How do I get a valid UUID token for a file that is already uploaded on Storage? Generating random UUID did not help. Any pointers?
              – DerFaizio
              Jun 16 '17 at 8:14






            • 2




              Found the answer in @martemorfosis post. The UUID can be retrieved from the object.metadata exports.uploadProfilePic = functions.storage.object().onChange(event => { const object = event.data; // The Storage object. const uuid = object.metadata.firebaseStorageDownloadTokens; // ...
              – DerFaizio
              Jun 16 '17 at 10:02












            • You Saved the day ,only working solution for me.
              – Rishabh Chandel
              Jun 22 '17 at 15:28










            • Thank you for the bucket example! I was trying different combinations for the bucket and file methods for almost 1 hour :)
              – JCarlos
              Aug 29 '17 at 18:34
















            30














            Here's an example on how to specify the download token on upload:



            const UUID = require("uuid-v4");

            const fbId = "<YOUR APP ID>";
            const fbKeyFile = "./YOUR_AUTH_FIlE.json";
            const gcs = require('@google-cloud/storage')({keyFilename: fbKeyFile});
            const bucket = gcs.bucket(`${fbId}.appspot.com`);

            var upload = (localFile, remoteFile) => {

            let uuid = UUID();

            return bucket.upload(localFile, {
            destination: remoteFile,
            uploadType: "media",
            metadata: {
            contentType: 'image/png',
            metadata: {
            firebaseStorageDownloadTokens: uuid
            }
            }
            })
            .then((data) => {

            let file = data[0];

            return Promise.resolve("https://firebasestorage.googleapis.com/v0/b/" + bucket.name + "/o/" + encodeURIComponent(file.name) + "?alt=media&token=" + uuid);
            });
            }


            then call with



            upload(localPath, remotePath).then( downloadURL => {
            console.log(downloadURL);
            });


            The key thing here is that there is a metadata object nested within the metadata option property. Setting firebaseStorageDownloadTokens to a uuid-v4 value will tell Cloud Storage to use that as its public auth token.



            Many thanks to @martemorfosis






            share|improve this answer























            • This is the only solution that worked for me!
              – Ari
              Jun 13 '17 at 22:19










            • How do I get a valid UUID token for a file that is already uploaded on Storage? Generating random UUID did not help. Any pointers?
              – DerFaizio
              Jun 16 '17 at 8:14






            • 2




              Found the answer in @martemorfosis post. The UUID can be retrieved from the object.metadata exports.uploadProfilePic = functions.storage.object().onChange(event => { const object = event.data; // The Storage object. const uuid = object.metadata.firebaseStorageDownloadTokens; // ...
              – DerFaizio
              Jun 16 '17 at 10:02












            • You Saved the day ,only working solution for me.
              – Rishabh Chandel
              Jun 22 '17 at 15:28










            • Thank you for the bucket example! I was trying different combinations for the bucket and file methods for almost 1 hour :)
              – JCarlos
              Aug 29 '17 at 18:34














            30












            30








            30






            Here's an example on how to specify the download token on upload:



            const UUID = require("uuid-v4");

            const fbId = "<YOUR APP ID>";
            const fbKeyFile = "./YOUR_AUTH_FIlE.json";
            const gcs = require('@google-cloud/storage')({keyFilename: fbKeyFile});
            const bucket = gcs.bucket(`${fbId}.appspot.com`);

            var upload = (localFile, remoteFile) => {

            let uuid = UUID();

            return bucket.upload(localFile, {
            destination: remoteFile,
            uploadType: "media",
            metadata: {
            contentType: 'image/png',
            metadata: {
            firebaseStorageDownloadTokens: uuid
            }
            }
            })
            .then((data) => {

            let file = data[0];

            return Promise.resolve("https://firebasestorage.googleapis.com/v0/b/" + bucket.name + "/o/" + encodeURIComponent(file.name) + "?alt=media&token=" + uuid);
            });
            }


            then call with



            upload(localPath, remotePath).then( downloadURL => {
            console.log(downloadURL);
            });


            The key thing here is that there is a metadata object nested within the metadata option property. Setting firebaseStorageDownloadTokens to a uuid-v4 value will tell Cloud Storage to use that as its public auth token.



            Many thanks to @martemorfosis






            share|improve this answer














            Here's an example on how to specify the download token on upload:



            const UUID = require("uuid-v4");

            const fbId = "<YOUR APP ID>";
            const fbKeyFile = "./YOUR_AUTH_FIlE.json";
            const gcs = require('@google-cloud/storage')({keyFilename: fbKeyFile});
            const bucket = gcs.bucket(`${fbId}.appspot.com`);

            var upload = (localFile, remoteFile) => {

            let uuid = UUID();

            return bucket.upload(localFile, {
            destination: remoteFile,
            uploadType: "media",
            metadata: {
            contentType: 'image/png',
            metadata: {
            firebaseStorageDownloadTokens: uuid
            }
            }
            })
            .then((data) => {

            let file = data[0];

            return Promise.resolve("https://firebasestorage.googleapis.com/v0/b/" + bucket.name + "/o/" + encodeURIComponent(file.name) + "?alt=media&token=" + uuid);
            });
            }


            then call with



            upload(localPath, remotePath).then( downloadURL => {
            console.log(downloadURL);
            });


            The key thing here is that there is a metadata object nested within the metadata option property. Setting firebaseStorageDownloadTokens to a uuid-v4 value will tell Cloud Storage to use that as its public auth token.



            Many thanks to @martemorfosis







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 2 '17 at 15:41









            Panagiotis Panagi

            7,23354391




            7,23354391










            answered May 3 '17 at 15:46









            Drew Beaupre

            1,3941216




            1,3941216












            • This is the only solution that worked for me!
              – Ari
              Jun 13 '17 at 22:19










            • How do I get a valid UUID token for a file that is already uploaded on Storage? Generating random UUID did not help. Any pointers?
              – DerFaizio
              Jun 16 '17 at 8:14






            • 2




              Found the answer in @martemorfosis post. The UUID can be retrieved from the object.metadata exports.uploadProfilePic = functions.storage.object().onChange(event => { const object = event.data; // The Storage object. const uuid = object.metadata.firebaseStorageDownloadTokens; // ...
              – DerFaizio
              Jun 16 '17 at 10:02












            • You Saved the day ,only working solution for me.
              – Rishabh Chandel
              Jun 22 '17 at 15:28










            • Thank you for the bucket example! I was trying different combinations for the bucket and file methods for almost 1 hour :)
              – JCarlos
              Aug 29 '17 at 18:34


















            • This is the only solution that worked for me!
              – Ari
              Jun 13 '17 at 22:19










            • How do I get a valid UUID token for a file that is already uploaded on Storage? Generating random UUID did not help. Any pointers?
              – DerFaizio
              Jun 16 '17 at 8:14






            • 2




              Found the answer in @martemorfosis post. The UUID can be retrieved from the object.metadata exports.uploadProfilePic = functions.storage.object().onChange(event => { const object = event.data; // The Storage object. const uuid = object.metadata.firebaseStorageDownloadTokens; // ...
              – DerFaizio
              Jun 16 '17 at 10:02












            • You Saved the day ,only working solution for me.
              – Rishabh Chandel
              Jun 22 '17 at 15:28










            • Thank you for the bucket example! I was trying different combinations for the bucket and file methods for almost 1 hour :)
              – JCarlos
              Aug 29 '17 at 18:34
















            This is the only solution that worked for me!
            – Ari
            Jun 13 '17 at 22:19




            This is the only solution that worked for me!
            – Ari
            Jun 13 '17 at 22:19












            How do I get a valid UUID token for a file that is already uploaded on Storage? Generating random UUID did not help. Any pointers?
            – DerFaizio
            Jun 16 '17 at 8:14




            How do I get a valid UUID token for a file that is already uploaded on Storage? Generating random UUID did not help. Any pointers?
            – DerFaizio
            Jun 16 '17 at 8:14




            2




            2




            Found the answer in @martemorfosis post. The UUID can be retrieved from the object.metadata exports.uploadProfilePic = functions.storage.object().onChange(event => { const object = event.data; // The Storage object. const uuid = object.metadata.firebaseStorageDownloadTokens; // ...
            – DerFaizio
            Jun 16 '17 at 10:02






            Found the answer in @martemorfosis post. The UUID can be retrieved from the object.metadata exports.uploadProfilePic = functions.storage.object().onChange(event => { const object = event.data; // The Storage object. const uuid = object.metadata.firebaseStorageDownloadTokens; // ...
            – DerFaizio
            Jun 16 '17 at 10:02














            You Saved the day ,only working solution for me.
            – Rishabh Chandel
            Jun 22 '17 at 15:28




            You Saved the day ,only working solution for me.
            – Rishabh Chandel
            Jun 22 '17 at 15:28












            Thank you for the bucket example! I was trying different combinations for the bucket and file methods for almost 1 hour :)
            – JCarlos
            Aug 29 '17 at 18:34




            Thank you for the bucket example! I was trying different combinations for the bucket and file methods for almost 1 hour :)
            – JCarlos
            Aug 29 '17 at 18:34











            11














            With the recent changes in the functions object response you can get everything you need to "stitch" together the download URL like so:



             const img_url = 'https://firebasestorage.googleapis.com/v0/b/[YOUR BUCKET]/o/'
            + encodeURIComponent(object.name)
            + '?alt=media&token='
            + object.metadata.firebaseStorageDownloadTokens;

            console.log('URL',img_url);





            share|improve this answer





















            • thanks, it works for me
              – postace
              May 9 '18 at 11:49






            • 1




              This is the correct answer.
              – Uriel Frankel
              May 18 '18 at 13:21










            • Are you referring to the object response from bucket.file().upload()? I don't receive any metadata property in the response data, and I'm not sure how to get these firebaseStorageDownloadTokens.
              – Dygerati
              Jul 11 '18 at 20:30










            • also [YOUR BUCKET] is bucket.name, you don't have to hardcode it or use an extra local var
              – Călin Darie
              Jul 13 '18 at 7:28






            • 2




              The problem with this solution is that the service URL is hardcoded. If the Firebase/Google change it, it may break. Using the metadata.mediaLink property prevents such an issue.
              – Laurent
              Aug 2 '18 at 13:39
















            11














            With the recent changes in the functions object response you can get everything you need to "stitch" together the download URL like so:



             const img_url = 'https://firebasestorage.googleapis.com/v0/b/[YOUR BUCKET]/o/'
            + encodeURIComponent(object.name)
            + '?alt=media&token='
            + object.metadata.firebaseStorageDownloadTokens;

            console.log('URL',img_url);





            share|improve this answer





















            • thanks, it works for me
              – postace
              May 9 '18 at 11:49






            • 1




              This is the correct answer.
              – Uriel Frankel
              May 18 '18 at 13:21










            • Are you referring to the object response from bucket.file().upload()? I don't receive any metadata property in the response data, and I'm not sure how to get these firebaseStorageDownloadTokens.
              – Dygerati
              Jul 11 '18 at 20:30










            • also [YOUR BUCKET] is bucket.name, you don't have to hardcode it or use an extra local var
              – Călin Darie
              Jul 13 '18 at 7:28






            • 2




              The problem with this solution is that the service URL is hardcoded. If the Firebase/Google change it, it may break. Using the metadata.mediaLink property prevents such an issue.
              – Laurent
              Aug 2 '18 at 13:39














            11












            11








            11






            With the recent changes in the functions object response you can get everything you need to "stitch" together the download URL like so:



             const img_url = 'https://firebasestorage.googleapis.com/v0/b/[YOUR BUCKET]/o/'
            + encodeURIComponent(object.name)
            + '?alt=media&token='
            + object.metadata.firebaseStorageDownloadTokens;

            console.log('URL',img_url);





            share|improve this answer












            With the recent changes in the functions object response you can get everything you need to "stitch" together the download URL like so:



             const img_url = 'https://firebasestorage.googleapis.com/v0/b/[YOUR BUCKET]/o/'
            + encodeURIComponent(object.name)
            + '?alt=media&token='
            + object.metadata.firebaseStorageDownloadTokens;

            console.log('URL',img_url);






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Apr 18 '18 at 2:02









            Demian S

            12115




            12115












            • thanks, it works for me
              – postace
              May 9 '18 at 11:49






            • 1




              This is the correct answer.
              – Uriel Frankel
              May 18 '18 at 13:21










            • Are you referring to the object response from bucket.file().upload()? I don't receive any metadata property in the response data, and I'm not sure how to get these firebaseStorageDownloadTokens.
              – Dygerati
              Jul 11 '18 at 20:30










            • also [YOUR BUCKET] is bucket.name, you don't have to hardcode it or use an extra local var
              – Călin Darie
              Jul 13 '18 at 7:28






            • 2




              The problem with this solution is that the service URL is hardcoded. If the Firebase/Google change it, it may break. Using the metadata.mediaLink property prevents such an issue.
              – Laurent
              Aug 2 '18 at 13:39


















            • thanks, it works for me
              – postace
              May 9 '18 at 11:49






            • 1




              This is the correct answer.
              – Uriel Frankel
              May 18 '18 at 13:21










            • Are you referring to the object response from bucket.file().upload()? I don't receive any metadata property in the response data, and I'm not sure how to get these firebaseStorageDownloadTokens.
              – Dygerati
              Jul 11 '18 at 20:30










            • also [YOUR BUCKET] is bucket.name, you don't have to hardcode it or use an extra local var
              – Călin Darie
              Jul 13 '18 at 7:28






            • 2




              The problem with this solution is that the service URL is hardcoded. If the Firebase/Google change it, it may break. Using the metadata.mediaLink property prevents such an issue.
              – Laurent
              Aug 2 '18 at 13:39
















            thanks, it works for me
            – postace
            May 9 '18 at 11:49




            thanks, it works for me
            – postace
            May 9 '18 at 11:49




            1




            1




            This is the correct answer.
            – Uriel Frankel
            May 18 '18 at 13:21




            This is the correct answer.
            – Uriel Frankel
            May 18 '18 at 13:21












            Are you referring to the object response from bucket.file().upload()? I don't receive any metadata property in the response data, and I'm not sure how to get these firebaseStorageDownloadTokens.
            – Dygerati
            Jul 11 '18 at 20:30




            Are you referring to the object response from bucket.file().upload()? I don't receive any metadata property in the response data, and I'm not sure how to get these firebaseStorageDownloadTokens.
            – Dygerati
            Jul 11 '18 at 20:30












            also [YOUR BUCKET] is bucket.name, you don't have to hardcode it or use an extra local var
            – Călin Darie
            Jul 13 '18 at 7:28




            also [YOUR BUCKET] is bucket.name, you don't have to hardcode it or use an extra local var
            – Călin Darie
            Jul 13 '18 at 7:28




            2




            2




            The problem with this solution is that the service URL is hardcoded. If the Firebase/Google change it, it may break. Using the metadata.mediaLink property prevents such an issue.
            – Laurent
            Aug 2 '18 at 13:39




            The problem with this solution is that the service URL is hardcoded. If the Firebase/Google change it, it may break. Using the metadata.mediaLink property prevents such an issue.
            – Laurent
            Aug 2 '18 at 13:39











            10














            One method I'm using with success is to set a UUID v4 value to a key named firebaseStorageDownloadTokens in the metadata of the file after it finishes uploading and then assemble the download URL myself following the structure Firebase uses to generate these URLs, eg:



            https://firebasestorage.googleapis.com/v0/b/[BUCKET_NAME]/o/[FILE_PATH]?alt=media&token=[THE_TOKEN_YOU_CREATED]


            I don't know how much "safe" is to use this method (given that Firebase could change how it generates the download URLs in the future ) but it is easy to implement.






            share|improve this answer





















            • Do you have an example where you set the uuid value?
              – Drew Beaupre
              May 2 '17 at 3:32






            • 1




              I've the same question as Drew, where do you set the metadata? I tried to set while bucket.upload function, didn't work.
              – Vysakh Sreenivasan
              May 3 '17 at 11:47






            • 1




              Vysakh, I've posted a complete answer w/ example. Hope that helps you.
              – Drew Beaupre
              May 3 '17 at 15:47










            • Where/how do you create the token?
              – CodyBugstein
              Jul 20 '18 at 3:01










            • I would not consider this technique "safe", as download URLs are meant to be opaque, whose components are not to be broken down or assembled.
              – Doug Stevenson
              Sep 17 '18 at 4:49
















            10














            One method I'm using with success is to set a UUID v4 value to a key named firebaseStorageDownloadTokens in the metadata of the file after it finishes uploading and then assemble the download URL myself following the structure Firebase uses to generate these URLs, eg:



            https://firebasestorage.googleapis.com/v0/b/[BUCKET_NAME]/o/[FILE_PATH]?alt=media&token=[THE_TOKEN_YOU_CREATED]


            I don't know how much "safe" is to use this method (given that Firebase could change how it generates the download URLs in the future ) but it is easy to implement.






            share|improve this answer





















            • Do you have an example where you set the uuid value?
              – Drew Beaupre
              May 2 '17 at 3:32






            • 1




              I've the same question as Drew, where do you set the metadata? I tried to set while bucket.upload function, didn't work.
              – Vysakh Sreenivasan
              May 3 '17 at 11:47






            • 1




              Vysakh, I've posted a complete answer w/ example. Hope that helps you.
              – Drew Beaupre
              May 3 '17 at 15:47










            • Where/how do you create the token?
              – CodyBugstein
              Jul 20 '18 at 3:01










            • I would not consider this technique "safe", as download URLs are meant to be opaque, whose components are not to be broken down or assembled.
              – Doug Stevenson
              Sep 17 '18 at 4:49














            10












            10








            10






            One method I'm using with success is to set a UUID v4 value to a key named firebaseStorageDownloadTokens in the metadata of the file after it finishes uploading and then assemble the download URL myself following the structure Firebase uses to generate these URLs, eg:



            https://firebasestorage.googleapis.com/v0/b/[BUCKET_NAME]/o/[FILE_PATH]?alt=media&token=[THE_TOKEN_YOU_CREATED]


            I don't know how much "safe" is to use this method (given that Firebase could change how it generates the download URLs in the future ) but it is easy to implement.






            share|improve this answer












            One method I'm using with success is to set a UUID v4 value to a key named firebaseStorageDownloadTokens in the metadata of the file after it finishes uploading and then assemble the download URL myself following the structure Firebase uses to generate these URLs, eg:



            https://firebasestorage.googleapis.com/v0/b/[BUCKET_NAME]/o/[FILE_PATH]?alt=media&token=[THE_TOKEN_YOU_CREATED]


            I don't know how much "safe" is to use this method (given that Firebase could change how it generates the download URLs in the future ) but it is easy to implement.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Apr 3 '17 at 23:15









            martemorfosis

            1094




            1094












            • Do you have an example where you set the uuid value?
              – Drew Beaupre
              May 2 '17 at 3:32






            • 1




              I've the same question as Drew, where do you set the metadata? I tried to set while bucket.upload function, didn't work.
              – Vysakh Sreenivasan
              May 3 '17 at 11:47






            • 1




              Vysakh, I've posted a complete answer w/ example. Hope that helps you.
              – Drew Beaupre
              May 3 '17 at 15:47










            • Where/how do you create the token?
              – CodyBugstein
              Jul 20 '18 at 3:01










            • I would not consider this technique "safe", as download URLs are meant to be opaque, whose components are not to be broken down or assembled.
              – Doug Stevenson
              Sep 17 '18 at 4:49


















            • Do you have an example where you set the uuid value?
              – Drew Beaupre
              May 2 '17 at 3:32






            • 1




              I've the same question as Drew, where do you set the metadata? I tried to set while bucket.upload function, didn't work.
              – Vysakh Sreenivasan
              May 3 '17 at 11:47






            • 1




              Vysakh, I've posted a complete answer w/ example. Hope that helps you.
              – Drew Beaupre
              May 3 '17 at 15:47










            • Where/how do you create the token?
              – CodyBugstein
              Jul 20 '18 at 3:01










            • I would not consider this technique "safe", as download URLs are meant to be opaque, whose components are not to be broken down or assembled.
              – Doug Stevenson
              Sep 17 '18 at 4:49
















            Do you have an example where you set the uuid value?
            – Drew Beaupre
            May 2 '17 at 3:32




            Do you have an example where you set the uuid value?
            – Drew Beaupre
            May 2 '17 at 3:32




            1




            1




            I've the same question as Drew, where do you set the metadata? I tried to set while bucket.upload function, didn't work.
            – Vysakh Sreenivasan
            May 3 '17 at 11:47




            I've the same question as Drew, where do you set the metadata? I tried to set while bucket.upload function, didn't work.
            – Vysakh Sreenivasan
            May 3 '17 at 11:47




            1




            1




            Vysakh, I've posted a complete answer w/ example. Hope that helps you.
            – Drew Beaupre
            May 3 '17 at 15:47




            Vysakh, I've posted a complete answer w/ example. Hope that helps you.
            – Drew Beaupre
            May 3 '17 at 15:47












            Where/how do you create the token?
            – CodyBugstein
            Jul 20 '18 at 3:01




            Where/how do you create the token?
            – CodyBugstein
            Jul 20 '18 at 3:01












            I would not consider this technique "safe", as download URLs are meant to be opaque, whose components are not to be broken down or assembled.
            – Doug Stevenson
            Sep 17 '18 at 4:49




            I would not consider this technique "safe", as download URLs are meant to be opaque, whose components are not to be broken down or assembled.
            – Doug Stevenson
            Sep 17 '18 at 4:49











            8














            For those wondering where the Firebase Admin SDK serviceAccountKey.json file should go. Just place it in the functions folder and deploy as usual.



            It still baffles me why we can't just get the download url from the metadata like we do in the Javascript SDK. Generating a url that will eventually expire and saving it in the database is not desirable.






            share|improve this answer





















            • You can do it, just look at my answer.
              – Laurent
              Nov 16 '18 at 19:59
















            8














            For those wondering where the Firebase Admin SDK serviceAccountKey.json file should go. Just place it in the functions folder and deploy as usual.



            It still baffles me why we can't just get the download url from the metadata like we do in the Javascript SDK. Generating a url that will eventually expire and saving it in the database is not desirable.






            share|improve this answer





















            • You can do it, just look at my answer.
              – Laurent
              Nov 16 '18 at 19:59














            8












            8








            8






            For those wondering where the Firebase Admin SDK serviceAccountKey.json file should go. Just place it in the functions folder and deploy as usual.



            It still baffles me why we can't just get the download url from the metadata like we do in the Javascript SDK. Generating a url that will eventually expire and saving it in the database is not desirable.






            share|improve this answer












            For those wondering where the Firebase Admin SDK serviceAccountKey.json file should go. Just place it in the functions folder and deploy as usual.



            It still baffles me why we can't just get the download url from the metadata like we do in the Javascript SDK. Generating a url that will eventually expire and saving it in the database is not desirable.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Apr 26 '17 at 15:00









            Clinton

            495312




            495312












            • You can do it, just look at my answer.
              – Laurent
              Nov 16 '18 at 19:59


















            • You can do it, just look at my answer.
              – Laurent
              Nov 16 '18 at 19:59
















            You can do it, just look at my answer.
            – Laurent
            Nov 16 '18 at 19:59




            You can do it, just look at my answer.
            – Laurent
            Nov 16 '18 at 19:59











            8














            I suggest using the option predefinedAcl: 'publicRead' when uploading a file with Cloud Storage NodeJS 1.6.x or +:



            const options = {
            destination: yourFileDestination,
            predefinedAcl: 'publicRead'
            };

            bucket.upload(attachment, options);


            Then, getting the public URL is as simple as:



            bucket.upload(attachment, options).then(result => {
            const file = result[0];
            return file.getMetadata();
            }).then(results => {
            const metadata = results[0];
            console.log('metadata=', metadata.mediaLink);
            }).catch(error => {
            console.error(error);
            });





            share|improve this answer























            • That does in fact appear to work. The only downside I see so far though is that if you hit the image in the URL bar of a browser, it will download the image instead of viewing it inline.
              – Michael Giovanni Pumo
              Nov 28 '18 at 15:14










            • file.getMetadata() did the trick for me after using the save() method on the file reference. Using it in NodeJS with firebase-admin sdk.
              – Pascal Lamers
              Dec 16 '18 at 23:34


















            8














            I suggest using the option predefinedAcl: 'publicRead' when uploading a file with Cloud Storage NodeJS 1.6.x or +:



            const options = {
            destination: yourFileDestination,
            predefinedAcl: 'publicRead'
            };

            bucket.upload(attachment, options);


            Then, getting the public URL is as simple as:



            bucket.upload(attachment, options).then(result => {
            const file = result[0];
            return file.getMetadata();
            }).then(results => {
            const metadata = results[0];
            console.log('metadata=', metadata.mediaLink);
            }).catch(error => {
            console.error(error);
            });





            share|improve this answer























            • That does in fact appear to work. The only downside I see so far though is that if you hit the image in the URL bar of a browser, it will download the image instead of viewing it inline.
              – Michael Giovanni Pumo
              Nov 28 '18 at 15:14










            • file.getMetadata() did the trick for me after using the save() method on the file reference. Using it in NodeJS with firebase-admin sdk.
              – Pascal Lamers
              Dec 16 '18 at 23:34
















            8












            8








            8






            I suggest using the option predefinedAcl: 'publicRead' when uploading a file with Cloud Storage NodeJS 1.6.x or +:



            const options = {
            destination: yourFileDestination,
            predefinedAcl: 'publicRead'
            };

            bucket.upload(attachment, options);


            Then, getting the public URL is as simple as:



            bucket.upload(attachment, options).then(result => {
            const file = result[0];
            return file.getMetadata();
            }).then(results => {
            const metadata = results[0];
            console.log('metadata=', metadata.mediaLink);
            }).catch(error => {
            console.error(error);
            });





            share|improve this answer














            I suggest using the option predefinedAcl: 'publicRead' when uploading a file with Cloud Storage NodeJS 1.6.x or +:



            const options = {
            destination: yourFileDestination,
            predefinedAcl: 'publicRead'
            };

            bucket.upload(attachment, options);


            Then, getting the public URL is as simple as:



            bucket.upload(attachment, options).then(result => {
            const file = result[0];
            return file.getMetadata();
            }).then(results => {
            const metadata = results[0];
            console.log('metadata=', metadata.mediaLink);
            }).catch(error => {
            console.error(error);
            });






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 16 '18 at 20:00

























            answered Mar 21 '18 at 16:03









            Laurent

            8,202103858




            8,202103858












            • That does in fact appear to work. The only downside I see so far though is that if you hit the image in the URL bar of a browser, it will download the image instead of viewing it inline.
              – Michael Giovanni Pumo
              Nov 28 '18 at 15:14










            • file.getMetadata() did the trick for me after using the save() method on the file reference. Using it in NodeJS with firebase-admin sdk.
              – Pascal Lamers
              Dec 16 '18 at 23:34




















            • That does in fact appear to work. The only downside I see so far though is that if you hit the image in the URL bar of a browser, it will download the image instead of viewing it inline.
              – Michael Giovanni Pumo
              Nov 28 '18 at 15:14










            • file.getMetadata() did the trick for me after using the save() method on the file reference. Using it in NodeJS with firebase-admin sdk.
              – Pascal Lamers
              Dec 16 '18 at 23:34


















            That does in fact appear to work. The only downside I see so far though is that if you hit the image in the URL bar of a browser, it will download the image instead of viewing it inline.
            – Michael Giovanni Pumo
            Nov 28 '18 at 15:14




            That does in fact appear to work. The only downside I see so far though is that if you hit the image in the URL bar of a browser, it will download the image instead of viewing it inline.
            – Michael Giovanni Pumo
            Nov 28 '18 at 15:14












            file.getMetadata() did the trick for me after using the save() method on the file reference. Using it in NodeJS with firebase-admin sdk.
            – Pascal Lamers
            Dec 16 '18 at 23:34






            file.getMetadata() did the trick for me after using the save() method on the file reference. Using it in NodeJS with firebase-admin sdk.
            – Pascal Lamers
            Dec 16 '18 at 23:34













            6














            Sorry but i can't post a comment to your question above because of missing reputation, so I will include it in this answer.



            Do as stated above by generating a signed Url, but instead of using the service-account.json I think you have to use the serviceAccountKey.json which you can generate at (replace YOURPROJECTID accordingly)



            https://console.firebase.google.com/project/YOURPROJECTID/settings/serviceaccounts/adminsdk



            Example:



            const gcs = require('@google-cloud/storage')({keyFilename: 'serviceAccountKey.json'});
            // ...
            const bucket = gcs.bucket(bucket);
            // ...
            return bucket.upload(tempLocalFile, {
            destination: filePath,
            metadata: {
            contentType: 'image/jpeg'
            }
            })
            .then((data) => {
            let file = data[0]
            file.getSignedUrl({
            action: 'read',
            expires: '03-17-2025'
            }, function(err, url) {
            if (err) {
            console.error(err);
            return;
            }

            // handle url
            })





            share|improve this answer


























              6














              Sorry but i can't post a comment to your question above because of missing reputation, so I will include it in this answer.



              Do as stated above by generating a signed Url, but instead of using the service-account.json I think you have to use the serviceAccountKey.json which you can generate at (replace YOURPROJECTID accordingly)



              https://console.firebase.google.com/project/YOURPROJECTID/settings/serviceaccounts/adminsdk



              Example:



              const gcs = require('@google-cloud/storage')({keyFilename: 'serviceAccountKey.json'});
              // ...
              const bucket = gcs.bucket(bucket);
              // ...
              return bucket.upload(tempLocalFile, {
              destination: filePath,
              metadata: {
              contentType: 'image/jpeg'
              }
              })
              .then((data) => {
              let file = data[0]
              file.getSignedUrl({
              action: 'read',
              expires: '03-17-2025'
              }, function(err, url) {
              if (err) {
              console.error(err);
              return;
              }

              // handle url
              })





              share|improve this answer
























                6












                6








                6






                Sorry but i can't post a comment to your question above because of missing reputation, so I will include it in this answer.



                Do as stated above by generating a signed Url, but instead of using the service-account.json I think you have to use the serviceAccountKey.json which you can generate at (replace YOURPROJECTID accordingly)



                https://console.firebase.google.com/project/YOURPROJECTID/settings/serviceaccounts/adminsdk



                Example:



                const gcs = require('@google-cloud/storage')({keyFilename: 'serviceAccountKey.json'});
                // ...
                const bucket = gcs.bucket(bucket);
                // ...
                return bucket.upload(tempLocalFile, {
                destination: filePath,
                metadata: {
                contentType: 'image/jpeg'
                }
                })
                .then((data) => {
                let file = data[0]
                file.getSignedUrl({
                action: 'read',
                expires: '03-17-2025'
                }, function(err, url) {
                if (err) {
                console.error(err);
                return;
                }

                // handle url
                })





                share|improve this answer












                Sorry but i can't post a comment to your question above because of missing reputation, so I will include it in this answer.



                Do as stated above by generating a signed Url, but instead of using the service-account.json I think you have to use the serviceAccountKey.json which you can generate at (replace YOURPROJECTID accordingly)



                https://console.firebase.google.com/project/YOURPROJECTID/settings/serviceaccounts/adminsdk



                Example:



                const gcs = require('@google-cloud/storage')({keyFilename: 'serviceAccountKey.json'});
                // ...
                const bucket = gcs.bucket(bucket);
                // ...
                return bucket.upload(tempLocalFile, {
                destination: filePath,
                metadata: {
                contentType: 'image/jpeg'
                }
                })
                .then((data) => {
                let file = data[0]
                file.getSignedUrl({
                action: 'read',
                expires: '03-17-2025'
                }, function(err, url) {
                if (err) {
                console.error(err);
                return;
                }

                // handle url
                })






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Mar 23 '17 at 9:36









                NiVeK92

                612




                612























                    3














                    If you're working on a Firebase project, you can create signed URLs in a Cloud Function without including other libraries or downloading a credentials file. You just need to enable the IAM API and add a role to your existing service account (see below).



                    Initialize the admin library and get a file reference as your normally would:



                    import * as functions from 'firebase-functions'
                    import * as admin from 'firebase-admin'

                    admin.initializeApp(functions.config().firebase)

                    const myFile = admin.storage().bucket().file('path/to/my/file')


                    You then generate a signed URL with



                    myFile.getSignedUrl({action: 'read', expires: someDateObj}).then(urls => {
                    const signedUrl = urls[0]
                    })


                    Make sure your Firebase service account has sufficient permissions to run this




                    1. Go to the Google API console and enable the IAM API (https://console.developers.google.com/apis/api/iam.googleapis.com/overview)

                    2. Still in the API console, go to the main menu, "IAM & admin" -> "IAM"

                    3. Click edit for the "App Engine default service account" role

                    4. Click "Add another role", and add the one called "Service Account Token Creator"

                    5. Save and wait a minute for the changes to propagate


                    With a vanilla Firebase config, the first time you run the above code you'll get an error Identity and Access Management (IAM) API has not been used in project XXXXXX before or it is disabled.. If you follow the link in the error message and enable the IAM API, you'll get another error: Permission iam.serviceAccounts.signBlob is required to perform this operation on service account my-service-account. Adding the Token Creator role fixes this second permission issue.






                    share|improve this answer





















                    • I was just about to leave an answer with basically these same details that I FINALLY figured out the hard way - sure wish I had read through the solutions this far down earlier :/ This worked for me as of 12/12/18. Thanks for the detailed instructions, very helpful for us beginners!!
                      – Kat
                      Dec 12 '18 at 15:29
















                    3














                    If you're working on a Firebase project, you can create signed URLs in a Cloud Function without including other libraries or downloading a credentials file. You just need to enable the IAM API and add a role to your existing service account (see below).



                    Initialize the admin library and get a file reference as your normally would:



                    import * as functions from 'firebase-functions'
                    import * as admin from 'firebase-admin'

                    admin.initializeApp(functions.config().firebase)

                    const myFile = admin.storage().bucket().file('path/to/my/file')


                    You then generate a signed URL with



                    myFile.getSignedUrl({action: 'read', expires: someDateObj}).then(urls => {
                    const signedUrl = urls[0]
                    })


                    Make sure your Firebase service account has sufficient permissions to run this




                    1. Go to the Google API console and enable the IAM API (https://console.developers.google.com/apis/api/iam.googleapis.com/overview)

                    2. Still in the API console, go to the main menu, "IAM & admin" -> "IAM"

                    3. Click edit for the "App Engine default service account" role

                    4. Click "Add another role", and add the one called "Service Account Token Creator"

                    5. Save and wait a minute for the changes to propagate


                    With a vanilla Firebase config, the first time you run the above code you'll get an error Identity and Access Management (IAM) API has not been used in project XXXXXX before or it is disabled.. If you follow the link in the error message and enable the IAM API, you'll get another error: Permission iam.serviceAccounts.signBlob is required to perform this operation on service account my-service-account. Adding the Token Creator role fixes this second permission issue.






                    share|improve this answer





















                    • I was just about to leave an answer with basically these same details that I FINALLY figured out the hard way - sure wish I had read through the solutions this far down earlier :/ This worked for me as of 12/12/18. Thanks for the detailed instructions, very helpful for us beginners!!
                      – Kat
                      Dec 12 '18 at 15:29














                    3












                    3








                    3






                    If you're working on a Firebase project, you can create signed URLs in a Cloud Function without including other libraries or downloading a credentials file. You just need to enable the IAM API and add a role to your existing service account (see below).



                    Initialize the admin library and get a file reference as your normally would:



                    import * as functions from 'firebase-functions'
                    import * as admin from 'firebase-admin'

                    admin.initializeApp(functions.config().firebase)

                    const myFile = admin.storage().bucket().file('path/to/my/file')


                    You then generate a signed URL with



                    myFile.getSignedUrl({action: 'read', expires: someDateObj}).then(urls => {
                    const signedUrl = urls[0]
                    })


                    Make sure your Firebase service account has sufficient permissions to run this




                    1. Go to the Google API console and enable the IAM API (https://console.developers.google.com/apis/api/iam.googleapis.com/overview)

                    2. Still in the API console, go to the main menu, "IAM & admin" -> "IAM"

                    3. Click edit for the "App Engine default service account" role

                    4. Click "Add another role", and add the one called "Service Account Token Creator"

                    5. Save and wait a minute for the changes to propagate


                    With a vanilla Firebase config, the first time you run the above code you'll get an error Identity and Access Management (IAM) API has not been used in project XXXXXX before or it is disabled.. If you follow the link in the error message and enable the IAM API, you'll get another error: Permission iam.serviceAccounts.signBlob is required to perform this operation on service account my-service-account. Adding the Token Creator role fixes this second permission issue.






                    share|improve this answer












                    If you're working on a Firebase project, you can create signed URLs in a Cloud Function without including other libraries or downloading a credentials file. You just need to enable the IAM API and add a role to your existing service account (see below).



                    Initialize the admin library and get a file reference as your normally would:



                    import * as functions from 'firebase-functions'
                    import * as admin from 'firebase-admin'

                    admin.initializeApp(functions.config().firebase)

                    const myFile = admin.storage().bucket().file('path/to/my/file')


                    You then generate a signed URL with



                    myFile.getSignedUrl({action: 'read', expires: someDateObj}).then(urls => {
                    const signedUrl = urls[0]
                    })


                    Make sure your Firebase service account has sufficient permissions to run this




                    1. Go to the Google API console and enable the IAM API (https://console.developers.google.com/apis/api/iam.googleapis.com/overview)

                    2. Still in the API console, go to the main menu, "IAM & admin" -> "IAM"

                    3. Click edit for the "App Engine default service account" role

                    4. Click "Add another role", and add the one called "Service Account Token Creator"

                    5. Save and wait a minute for the changes to propagate


                    With a vanilla Firebase config, the first time you run the above code you'll get an error Identity and Access Management (IAM) API has not been used in project XXXXXX before or it is disabled.. If you follow the link in the error message and enable the IAM API, you'll get another error: Permission iam.serviceAccounts.signBlob is required to perform this operation on service account my-service-account. Adding the Token Creator role fixes this second permission issue.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Nov 7 '18 at 19:27









                    SMX

                    627610




                    627610












                    • I was just about to leave an answer with basically these same details that I FINALLY figured out the hard way - sure wish I had read through the solutions this far down earlier :/ This worked for me as of 12/12/18. Thanks for the detailed instructions, very helpful for us beginners!!
                      – Kat
                      Dec 12 '18 at 15:29


















                    • I was just about to leave an answer with basically these same details that I FINALLY figured out the hard way - sure wish I had read through the solutions this far down earlier :/ This worked for me as of 12/12/18. Thanks for the detailed instructions, very helpful for us beginners!!
                      – Kat
                      Dec 12 '18 at 15:29
















                    I was just about to leave an answer with basically these same details that I FINALLY figured out the hard way - sure wish I had read through the solutions this far down earlier :/ This worked for me as of 12/12/18. Thanks for the detailed instructions, very helpful for us beginners!!
                    – Kat
                    Dec 12 '18 at 15:29




                    I was just about to leave an answer with basically these same details that I FINALLY figured out the hard way - sure wish I had read through the solutions this far down earlier :/ This worked for me as of 12/12/18. Thanks for the detailed instructions, very helpful for us beginners!!
                    – Kat
                    Dec 12 '18 at 15:29











                    1














                    This works if you just need a public file with a simple URL. Note that this may overrule your Firebase storage rules.



                    bucket.upload(file, function(err, file) {
                    if (!err) {
                    //Make the file public
                    file.acl.add({
                    entity: 'allUsers',
                    role: gcs.acl.READER_ROLE
                    }, function(err, aclObject) {
                    if (!err) {
                    var URL = "https://storage.googleapis.com/[your bucket name]/" + file.id;
                    console.log(URL);
                    } else {
                    console.log("Failed to set permissions: " + err);
                    }
                    });
                    } else {
                    console.log("Upload failed: " + err);
                    }
                    });





                    share|improve this answer




























                      1














                      This works if you just need a public file with a simple URL. Note that this may overrule your Firebase storage rules.



                      bucket.upload(file, function(err, file) {
                      if (!err) {
                      //Make the file public
                      file.acl.add({
                      entity: 'allUsers',
                      role: gcs.acl.READER_ROLE
                      }, function(err, aclObject) {
                      if (!err) {
                      var URL = "https://storage.googleapis.com/[your bucket name]/" + file.id;
                      console.log(URL);
                      } else {
                      console.log("Failed to set permissions: " + err);
                      }
                      });
                      } else {
                      console.log("Upload failed: " + err);
                      }
                      });





                      share|improve this answer


























                        1












                        1








                        1






                        This works if you just need a public file with a simple URL. Note that this may overrule your Firebase storage rules.



                        bucket.upload(file, function(err, file) {
                        if (!err) {
                        //Make the file public
                        file.acl.add({
                        entity: 'allUsers',
                        role: gcs.acl.READER_ROLE
                        }, function(err, aclObject) {
                        if (!err) {
                        var URL = "https://storage.googleapis.com/[your bucket name]/" + file.id;
                        console.log(URL);
                        } else {
                        console.log("Failed to set permissions: " + err);
                        }
                        });
                        } else {
                        console.log("Upload failed: " + err);
                        }
                        });





                        share|improve this answer














                        This works if you just need a public file with a simple URL. Note that this may overrule your Firebase storage rules.



                        bucket.upload(file, function(err, file) {
                        if (!err) {
                        //Make the file public
                        file.acl.add({
                        entity: 'allUsers',
                        role: gcs.acl.READER_ROLE
                        }, function(err, aclObject) {
                        if (!err) {
                        var URL = "https://storage.googleapis.com/[your bucket name]/" + file.id;
                        console.log(URL);
                        } else {
                        console.log("Failed to set permissions: " + err);
                        }
                        });
                        } else {
                        console.log("Upload failed: " + err);
                        }
                        });






                        share|improve this answer














                        share|improve this answer



                        share|improve this answer








                        edited Jan 14 '18 at 13:18

























                        answered Jan 14 '18 at 12:34









                        Dakine

                        235




                        235























                            1














                            I can't comment on the answer James Daniels gave, but I think this is very Important to read.



                            Giving out a signed URL Like he did seems for many cases pretty bad and possible Dangerous.
                            According to the documentation of Firebase the signed url expires after some time, so adding that to your databse will lead to a empty url after a certain timeframe



                            It may be that misunderstood the Documentation there and the signed url doesn't expire, which would have some security issues as a result.
                            The Key seems to be the same for every uploaded file. This means once you got the url of one file, someone could easily access files that he is not suposed to access, just by knowing their names.



                            If i missunderstood that then i would lvoe to be corrected.
                            Else someone should probably Update the above named solution.
                            If i may be wrong there






                            share|improve this answer


























                              1














                              I can't comment on the answer James Daniels gave, but I think this is very Important to read.



                              Giving out a signed URL Like he did seems for many cases pretty bad and possible Dangerous.
                              According to the documentation of Firebase the signed url expires after some time, so adding that to your databse will lead to a empty url after a certain timeframe



                              It may be that misunderstood the Documentation there and the signed url doesn't expire, which would have some security issues as a result.
                              The Key seems to be the same for every uploaded file. This means once you got the url of one file, someone could easily access files that he is not suposed to access, just by knowing their names.



                              If i missunderstood that then i would lvoe to be corrected.
                              Else someone should probably Update the above named solution.
                              If i may be wrong there






                              share|improve this answer
























                                1












                                1








                                1






                                I can't comment on the answer James Daniels gave, but I think this is very Important to read.



                                Giving out a signed URL Like he did seems for many cases pretty bad and possible Dangerous.
                                According to the documentation of Firebase the signed url expires after some time, so adding that to your databse will lead to a empty url after a certain timeframe



                                It may be that misunderstood the Documentation there and the signed url doesn't expire, which would have some security issues as a result.
                                The Key seems to be the same for every uploaded file. This means once you got the url of one file, someone could easily access files that he is not suposed to access, just by knowing their names.



                                If i missunderstood that then i would lvoe to be corrected.
                                Else someone should probably Update the above named solution.
                                If i may be wrong there






                                share|improve this answer












                                I can't comment on the answer James Daniels gave, but I think this is very Important to read.



                                Giving out a signed URL Like he did seems for many cases pretty bad and possible Dangerous.
                                According to the documentation of Firebase the signed url expires after some time, so adding that to your databse will lead to a empty url after a certain timeframe



                                It may be that misunderstood the Documentation there and the signed url doesn't expire, which would have some security issues as a result.
                                The Key seems to be the same for every uploaded file. This means once you got the url of one file, someone could easily access files that he is not suposed to access, just by knowing their names.



                                If i missunderstood that then i would lvoe to be corrected.
                                Else someone should probably Update the above named solution.
                                If i may be wrong there







                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered Apr 30 '18 at 21:09









                                Renji

                                407




                                407























                                    1














                                    For those who are using Firebase SDK andadmin.initializeApp:



                                    1 - Generate a Private Key and place in /functions folder.



                                    2 - Configure your code as follows:



                                    const serviceAccount = require('../../serviceAccountKey.json');
                                    try { admin.initializeApp(Object.assign(functions.config().firebase, { credential: admin.credential.cert(serviceAccount) })); } catch (e) {}


                                    Documentation



                                    The try/catch is because I'm using a index.js that imports other files and creates one function to each file. If you're using a single index.js file with all functions, you should be ok with admin.initializeApp(Object.assign(functions.config().firebase, { credential: admin.credential.cert(serviceAccount) }));.






                                    share|improve this answer





















                                    • for me it was '../serviceaccountkey.json' but thanks for the heads up to use the ../
                                      – robert king
                                      Nov 12 '18 at 12:34
















                                    1














                                    For those who are using Firebase SDK andadmin.initializeApp:



                                    1 - Generate a Private Key and place in /functions folder.



                                    2 - Configure your code as follows:



                                    const serviceAccount = require('../../serviceAccountKey.json');
                                    try { admin.initializeApp(Object.assign(functions.config().firebase, { credential: admin.credential.cert(serviceAccount) })); } catch (e) {}


                                    Documentation



                                    The try/catch is because I'm using a index.js that imports other files and creates one function to each file. If you're using a single index.js file with all functions, you should be ok with admin.initializeApp(Object.assign(functions.config().firebase, { credential: admin.credential.cert(serviceAccount) }));.






                                    share|improve this answer





















                                    • for me it was '../serviceaccountkey.json' but thanks for the heads up to use the ../
                                      – robert king
                                      Nov 12 '18 at 12:34














                                    1












                                    1








                                    1






                                    For those who are using Firebase SDK andadmin.initializeApp:



                                    1 - Generate a Private Key and place in /functions folder.



                                    2 - Configure your code as follows:



                                    const serviceAccount = require('../../serviceAccountKey.json');
                                    try { admin.initializeApp(Object.assign(functions.config().firebase, { credential: admin.credential.cert(serviceAccount) })); } catch (e) {}


                                    Documentation



                                    The try/catch is because I'm using a index.js that imports other files and creates one function to each file. If you're using a single index.js file with all functions, you should be ok with admin.initializeApp(Object.assign(functions.config().firebase, { credential: admin.credential.cert(serviceAccount) }));.






                                    share|improve this answer












                                    For those who are using Firebase SDK andadmin.initializeApp:



                                    1 - Generate a Private Key and place in /functions folder.



                                    2 - Configure your code as follows:



                                    const serviceAccount = require('../../serviceAccountKey.json');
                                    try { admin.initializeApp(Object.assign(functions.config().firebase, { credential: admin.credential.cert(serviceAccount) })); } catch (e) {}


                                    Documentation



                                    The try/catch is because I'm using a index.js that imports other files and creates one function to each file. If you're using a single index.js file with all functions, you should be ok with admin.initializeApp(Object.assign(functions.config().firebase, { credential: admin.credential.cert(serviceAccount) }));.







                                    share|improve this answer












                                    share|improve this answer



                                    share|improve this answer










                                    answered May 18 '18 at 19:02









                                    Allan Poppe

                                    544




                                    544












                                    • for me it was '../serviceaccountkey.json' but thanks for the heads up to use the ../
                                      – robert king
                                      Nov 12 '18 at 12:34


















                                    • for me it was '../serviceaccountkey.json' but thanks for the heads up to use the ../
                                      – robert king
                                      Nov 12 '18 at 12:34
















                                    for me it was '../serviceaccountkey.json' but thanks for the heads up to use the ../
                                    – robert king
                                    Nov 12 '18 at 12:34




                                    for me it was '../serviceaccountkey.json' but thanks for the heads up to use the ../
                                    – robert king
                                    Nov 12 '18 at 12:34











                                    1














                                    I had the same issue, however, I was looking at the code of the firebase function example instead of the README. And Answers on this thread didn't help either...



                                    You can avoid passing the config file by doing the following:




                                    Go to your project's Cloud Console > IAM & admin > IAM, Find the App
                                    Engine default service account and add the Service Account Token
                                    Creator role to that member. This will allow your app to create signed
                                    public URLs to the images.




                                    source: Automatically Generate Thumbnails function README



                                    Your role for app engine should look like this:



                                    Cloud Console






                                    share|improve this answer


























                                      1














                                      I had the same issue, however, I was looking at the code of the firebase function example instead of the README. And Answers on this thread didn't help either...



                                      You can avoid passing the config file by doing the following:




                                      Go to your project's Cloud Console > IAM & admin > IAM, Find the App
                                      Engine default service account and add the Service Account Token
                                      Creator role to that member. This will allow your app to create signed
                                      public URLs to the images.




                                      source: Automatically Generate Thumbnails function README



                                      Your role for app engine should look like this:



                                      Cloud Console






                                      share|improve this answer
























                                        1












                                        1








                                        1






                                        I had the same issue, however, I was looking at the code of the firebase function example instead of the README. And Answers on this thread didn't help either...



                                        You can avoid passing the config file by doing the following:




                                        Go to your project's Cloud Console > IAM & admin > IAM, Find the App
                                        Engine default service account and add the Service Account Token
                                        Creator role to that member. This will allow your app to create signed
                                        public URLs to the images.




                                        source: Automatically Generate Thumbnails function README



                                        Your role for app engine should look like this:



                                        Cloud Console






                                        share|improve this answer












                                        I had the same issue, however, I was looking at the code of the firebase function example instead of the README. And Answers on this thread didn't help either...



                                        You can avoid passing the config file by doing the following:




                                        Go to your project's Cloud Console > IAM & admin > IAM, Find the App
                                        Engine default service account and add the Service Account Token
                                        Creator role to that member. This will allow your app to create signed
                                        public URLs to the images.




                                        source: Automatically Generate Thumbnails function README



                                        Your role for app engine should look like this:



                                        Cloud Console







                                        share|improve this answer












                                        share|improve this answer



                                        share|improve this answer










                                        answered Oct 24 '18 at 13:41









                                        TheFullResolution

                                        446820




                                        446820























                                            0














                                            As of firebase 6.0.0 I was able to access the storage directly with the admin like this:



                                            const bucket = admin.storage().bucket();


                                            So I didn't need to add a service account. Then setting the UUID as referenced above worked for getting the firebase url.






                                            share|improve this answer




























                                              0














                                              As of firebase 6.0.0 I was able to access the storage directly with the admin like this:



                                              const bucket = admin.storage().bucket();


                                              So I didn't need to add a service account. Then setting the UUID as referenced above worked for getting the firebase url.






                                              share|improve this answer


























                                                0












                                                0








                                                0






                                                As of firebase 6.0.0 I was able to access the storage directly with the admin like this:



                                                const bucket = admin.storage().bucket();


                                                So I didn't need to add a service account. Then setting the UUID as referenced above worked for getting the firebase url.






                                                share|improve this answer














                                                As of firebase 6.0.0 I was able to access the storage directly with the admin like this:



                                                const bucket = admin.storage().bucket();


                                                So I didn't need to add a service account. Then setting the UUID as referenced above worked for getting the firebase url.







                                                share|improve this answer














                                                share|improve this answer



                                                share|improve this answer








                                                edited Nov 5 '18 at 1:31









                                                Stephen Rauch

                                                27.7k153256




                                                27.7k153256










                                                answered Nov 5 '18 at 1:15









                                                NickJ

                                                594




                                                594






























                                                    draft saved

                                                    draft discarded




















































                                                    Thanks for contributing an answer to Stack Overflow!


                                                    • Please be sure to answer the question. Provide details and share your research!

                                                    But avoid



                                                    • Asking for help, clarification, or responding to other answers.

                                                    • Making statements based on opinion; back them up with references or personal experience.


                                                    To learn more, see our tips on writing great answers.





                                                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                                    Please pay close attention to the following guidance:


                                                    • Please be sure to answer the question. Provide details and share your research!

                                                    But avoid



                                                    • Asking for help, clarification, or responding to other answers.

                                                    • Making statements based on opinion; back them up with references or personal experience.


                                                    To learn more, see our tips on writing great answers.




                                                    draft saved


                                                    draft discarded














                                                    StackExchange.ready(
                                                    function () {
                                                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f42956250%2fget-download-url-from-file-uploaded-with-cloud-functions-for-firebase%23new-answer', 'question_page');
                                                    }
                                                    );

                                                    Post as a guest















                                                    Required, but never shown





















































                                                    Required, but never shown














                                                    Required, but never shown












                                                    Required, but never shown







                                                    Required, but never shown

































                                                    Required, but never shown














                                                    Required, but never shown












                                                    Required, but never shown







                                                    Required, but never shown







                                                    這個網誌中的熱門文章

                                                    Xamarin.form Move up view when keyboard appear

                                                    Post-Redirect-Get with Spring WebFlux and Thymeleaf

                                                    Anylogic : not able to use stopDelay()