Как получить общедоступную ссылку для загрузки в функции запуска хранилища Firebase: «onFinalize»? - PullRequest
0 голосов
/ 07 ноября 2018

Я пишу облачную функцию Firebase, которая записывает ссылку для загрузки недавно загруженного файла в базу данных в реальном времени:

exports.recordImage = functions.storage.object().onFinalize((object) => {

});

«объект» дает мне доступ к двум переменным «selfLink» и «mediaLink», но обе они при вводе в браузере возвращают следующее:

Anonymous caller does not have storage.objects.get access to ... {filename}

Итак, они не являются публичными ссылками. Как я могу получить общедоступную ссылку для скачивания в этой функции триггера?

Ответы [ 2 ]

0 голосов
/ 12 декабря 2018

* используйте эту функцию:

function mediaLinkToDownloadableUrl(object) {
        var firstPartUrl = object.mediaLink.split("?")[0] // 'https://www.googleapis.com/download/storage/v1/b/abcbucket.appspot.com/o/songs%2Fsong1.mp3.mp3'
        var secondPartUrl = object.mediaLink.split("?")[1] // 'generation=123445678912345&alt=media'

        firstPartUrl = firstPartUrl.replace("https://www.googleapis.com/download/storage", "https://firebasestorage.googleapis.com")
        firstPartUrl = firstPartUrl.replace("v1", "v0")

        firstPartUrl += "?" + secondPartUrl.split("&")[1]; // 'alt=media'
        firstPartUrl += "&token=" + object.metadata.firebaseStorageDownloadTokens

        return firstPartUrl
    }

вот так может выглядеть ваш код:

export const onAddSong = functions.storage.object().onFinalize((object) => {

    console.log("object: ", object);

    var url = mediaLinkToDownloadableUrl(object);

    //do anything with url, like send via email or save it in your database in playlist table 
    //in my case I'm saving it in mongodb database

    return new playlistModel({
        name: storyName,
        mp3Url: url,
        ownerEmail: ownerEmail
    })
    .save() // I'm doing nothing on save complete
    .catch(e => {
        console.log(e) // log if error occur in database write
    })

})

* Я проверил этот метод на mp3-файлах, я уверен, что он будет работать на всех типах файлов, но если он у вас не сработает, просто перейдите на панель управления хранилищем данных firebase, откройте любой файл и скопируйте URL-адрес загрузки и попробуйте сгенерируйте тот же URL в вашем коде и, если возможно, отредактируйте этот ответ

0 голосов
/ 07 ноября 2018

Вы должны использовать асинхронный метод getSignedUrl(), см. Документ библиотеки Cloud Storage Node.js: https://cloud.google.com/nodejs/docs/reference/storage/2.0.x/File#getSignedUrl.

Так что следующий код должен сработать:

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

exports.recordImage = functions.storage.object().onFinalize(object => {    
  const bucket = defaultStorage.bucket();
  const file = bucket.file(object.name);

  const options = {
    action: 'read',
    expires: '03-17-2025'
  };

  // Get a signed URL for the file
  return file
    .getSignedUrl(options)
    .then(results => {
      const url = results[0];

      console.log(`The signed url for ${filename} is ${url}.`);
      return true;
    })

});

Обратите внимание, что для использования метода getSignedUrl() вам нужно инициализировать Admin SDK с учетными данными для выделенной учетной записи службы, см. Этот вопрос запустить облачное хранилище .

...