Как загрузить изображение в хранилище Firebase с помощью Node.js и получить его общедоступный URL? [Дубликат]

Я не уверен, что вы подразумеваете под «отменой» изменения. Вы можете удалить настройку core.excludesfile следующим образом:

git config --global --unset core.excludesfile

И, конечно, вы можете просто отредактировать файл конфигурации:

git config --global --edit

... и затем удалить настройку вручную.

43
задан Brian Burns 17 March 2018 в 11:13
поделиться

11 ответов

Вам нужно создать подписанный URL-адрес, используя getSignedURL с помощью модуля @ google-cloud / storage NPM.

Пример:

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
});

Вам нужно будет инициализировать @google-cloud/storage с помощью учетных данных вашей учетной записи службы , поскольку учетные данные по умолчанию для приложения будут недостаточными.

UPDATE: The Cloud Теперь SDK хранилища можно получить через SDK Firebase Admin, который действует как обертка в области @ облака / хранилища Google. Вам все равно придется запустить SDK с учетной записью службы, как правило, через второй экземпляр, отличный от стандартного.

55
ответ дан Doug Stevenson 15 August 2018 в 21:22
поделиться
  • 1
    Это странно. Мы можем легко получить URL-адрес Download из ссылки Storage при использовании Firebase Android, iOS и Web SDK. Почему это не так просто, когда вы находитесь в админ? PS: Где я могу найти «service-account.json», необходимый для инициализации gcs? – Valentin 23 March 2017 в 09:26
  • 2
    Это связано с тем, что в admin-sdk нет добавок Cloud Storage. Вы можете получить свою учетную запись службы admin-sdk json здесь console.firebase.google.com/project / _ / settings / servicesaccounts / & hellip; – James Daniels 23 March 2017 в 18:46
  • 3
    Правда, но ни один из документов не использует getSignedUrl, что я буду исправлять github.com/firebase/functions-samples/issues/82 . По словам Като, мы делаем это в кодеделе. – James Daniels 1 April 2017 в 02:21
  • 4
    URL, сгенерированный с помощью этого метода, смехотворно длинный. URL-адрес, созданный предложенным методом @martemorfosis, намного лучше. Есть ли какая-либо функция, которая создает этот URL-адрес? Это то, что я сохраняю в базе данных для будущего использования, когда я использую firebase-sdk. Зеркальный метод должен существовать в области функций. – Bogac 19 April 2017 в 16:29
  • 5
    Как мы можем загрузить службу-account.json по развернутым функциям? Я попытался поместить его в папку функций и ссылаться на него в поле файла в package.json, но он не развертывается. Спасибо. – José David Aroesti 25 April 2017 в 18:20

Для тех, кто использует Firebase SDK и admin.initializeApp:

1 - Создайте закрытый ключ и поместите в папку / functions.

2 - Настройте свой код следующим образом:

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

Документация

Try / catch - это потому, что я использую index.js, который импортирует другие файлы и создает одну функцию для каждого файла. Если вы используете один файл index.js со всеми функциями, вы должны быть в порядке с admin.initializeApp(Object.assign(functions.config().firebase, { credential: admin.credential.cert(serviceAccount) }));.

0
ответ дан Allan Poppe 15 August 2018 в 21:22
поделиться

Для тех, кто задается вопросом, куда должен идти файл службы Firebase Admin SDK serviceAccountKey.json. Просто поместите его в папку функций и разверните, как обычно.

Это все еще озадачивает меня, почему мы не можем просто получить URL-адрес загрузки из метаданных, как в Javascript SDK. Создание URL-адреса, которое в конечном итоге истечет и сохранить его в базе данных, нежелательно.

8
ответ дан Clinton 15 August 2018 в 21:22
поделиться

Это работает, если вам нужен только общий файл с простым URL-адресом. Обратите внимание, что это может привести к отмене ваших правил хранения Firebase.

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);
    }
});
1
ответ дан Dakine 15 August 2018 в 21:22
поделиться

С недавними изменениями в ответе объекта функций вы можете получить все, что вам нужно, чтобы «сшить» вместе URL загрузки так:

 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);
6
ответ дан Demian S 15 August 2018 в 21:22
поделиться
  • 1
    спасибо, это работает для меня – postace 9 May 2018 в 11:49
  • 2
    Это правильный ответ. – Uriel Frankel 18 May 2018 в 13:21
  • 3
    Вы имеете в виду ответ объекта из bucket.file().upload()? Я не получаю никакого свойства метаданных в данных ответа, и я не уверен, как получить эти firebaseStorageDownloadTokens. – Dygerati 11 July 2018 в 20:30
  • 4
    также [YOUR BUCKET] - bucket.name, вам не нужно жестко указывать его или использовать дополнительный локальный var – Călin Darie 13 July 2018 в 07:28
  • 5
    Проблема с этим решением заключается в том, что URL-адрес службы жестко запрограммирован. Если Firebase / Google изменит его, он может сломаться. Использование свойства metadata.mediaLink предотвращает такую ​​проблему. – Laurent 2 August 2018 в 13:39

Я предлагаю использовать параметр predefinedAcl: 'publicRead' при загрузке файла с помощью Cloud Storage NodeJS 1.6.x :

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

bucket.upload(attachment, options);

. Затем получение общедоступного URL-адреса так же просто, как и :

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);
});
4
ответ дан Laurent 15 August 2018 в 21:22
поделиться

Один из методов, который я использую с успехом, заключается в том, чтобы установить значение UUID v4 в ключе с именем firebaseStorageDownloadTokens в метаданных файла после завершения загрузки, а затем собрать URL-адрес загрузки, следуя структуре Firebase, используемой для создания этих URL, например:

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

Я не знаю, насколько «безопасно» использовать этот метод (учитывая, что Firebase может изменить способ генерации URL-адресов загрузки в будущем), но это легко реализовать.

10
ответ дан martemorfosis 15 August 2018 в 21:22
поделиться
  • 1
    У вас есть пример, где вы устанавливаете значение uuid? – Drew Beaupre 2 May 2017 в 03:32
  • 2
    У меня такой же вопрос, как у Дрю, где вы устанавливаете метаданные? Я пытался установить функцию bucket.upload, не работал. – Vysakh Sreenivasan 3 May 2017 в 11:47
  • 3
    Вышак, я опубликовал полный ответ с примером. Надеюсь, что это поможет тебе. – Drew Beaupre 3 May 2017 в 15:47
  • 4
    Где / как вы создаете токен? – CodyBugstein 20 July 2018 в 03:01
  • 5
    – Doug Stevenson 17 September 2018 в 04:49

Извините, но я не могу опубликовать комментарий к вашему вопросу выше из-за отсутствия репутации, поэтому я включу его в этот ответ.

Сделайте, как указано выше, создав подписанный Url, но вместо используя service-account.json. Я думаю, вам нужно использовать serviceAccountKey.json, который вы можете создать (замените YOURPROJECTID соответственно)

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

Пример:

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 
        })
6
ответ дан NiVeK92 15 August 2018 в 21:22
поделиться

Вот пример того, как указать токен загрузки при загрузке:

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);
      });
}

, а затем позвонить с помощью

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

. Главное, что есть metadata, вложенных в свойство опции metadata. Установка firebaseStorageDownloadTokens в значение uuid-v4 сообщит Cloud Storage, чтобы использовать это как общедоступный токен аутентификации.

Большое спасибо @martemorfosis

23
ответ дан Panagiotis Panagi 15 August 2018 в 21:22
поделиться
  • 1
    Это единственное решение, которое сработало для меня! – Ari 13 June 2017 в 22:19
  • 2
    Как получить действительный токен UUID для файла, который уже загружен в хранилище? Генерация случайного UUID не помогла. Любые указатели? – DerFaizio 16 June 2017 в 08:14
  • 3
    Нашел ответ на пост @martemorfosis. UUID может быть извлечен из объекта. Metadata export.uploadProfilePic = functions.storage.object (). OnChange (event = & gt; {const object = event.data; // Объект Storage. Const uuid = object.metadata.firebaseStorageDownloadTokens ; // ... – DerFaizio 16 June 2017 в 10:02
  • 4
    Вы сохранили этот день, только работая для меня. – Rishabh Chandel 22 June 2017 в 15:28
  • 5
    Спасибо за пример с ведром! Я пробовал разные комбинации для ведра и файловых методов почти 1 час :) – JCarlos 29 August 2017 в 18:34

Я не могу прокомментировать ответ, который дал Джеймс Дэниелс, но я думаю, что это очень важно прочитать.

Выдача подписанного URL-адреса. Как и во многих случаях, это довольно плохо и возможно опасно. Согласно документации Firebase, подписанный URL-адрес истекает через некоторое время, поэтому добавление этого к вашей базе данных приведет к пустым URL-адресам после определенного таймфрейма

Возможно, это неправильно понимает Документацию там, и подписанный url doesn истекает, что приведет к некоторым проблемам безопасности. Кажется, что ключ для каждого загруженного файла одинаковый. Это означает, что как только вы получите URL-адрес одного файла, кто-то может легко получить доступ к файлам, к которым он не предназначен для доступа, просто зная их имена.

Если я не понял, что тогда я буду исправлять lvoe. Кроме того, кто-то должен, вероятно, обновить вышеупомянутое решение. Если я ошибаюсь,

0
ответ дан Renji 15 August 2018 в 21:22
поделиться
0
ответ дан TheFullResolution 29 October 2018 в 04:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: