Получить публичный URL из файла, загруженного с помощью firebase-admin

Я использую firebase-admin и firebase-функции для загрузки файла в Firebase Storage.

У меня есть эти правила в хранилище:

service firebase.storage {
  match /b/{bucket}/o {
    match /images {
      allow read;
      allow write: if false;
    }
  }
}

И я хочу получить публичный URL с этим кодом:

const config = functions.config().firebase;
const firebase = admin.initializeApp(config);
const bucketRef = firebase.storage();

server.post('/upload', async (req, res) => {

  // UPLOAD FILE

  await stream.on('finish', async () => {
        const fileUrl = bucketRef
          .child(`images/${fileName}`)
          .getDownloadUrl()
          .getResult();
        return res.status(200).send(fileUrl);
      });
});

Но у меня есть эта ошибка .child is not a function, Как я могу получить публичный URL файла с помощью firebase-admin?

4 ответа

Решение

Из примера кода приложения в документации по Cloud Storage вы сможете реализовать следующий код, чтобы получить общедоступный URL-адрес для загрузки после успешной загрузки:

// Create a new blob in the bucket and upload the file data.
const blob = bucket.file(req.file.originalname);
const blobStream = blob.createWriteStream();

blobStream.on('finish', () => {
    // The public URL can be used to directly access the file via HTTP.
    const publicUrl = format(`https://storage.googleapis.com/${bucket.name}/${blob.name}`);
    res.status(200).send(publicUrl);
});

Кроме того, если вам нужен общедоступный URL-адрес для загрузки, см. Этот ответ, в котором предлагается использовать getSignedUrl() из модуля Cloud Storage NPM, потому что Admin SDK не поддерживает это напрямую:

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

Пример:

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

Что сработало для меня, так это составить такой URL-адрес:

https://storage.googleapis.com/<bucketName>/<pathToFile>

Пример: https://storage.googleapis.com/mybucket.appspot.com/public/myFile.png.

Как я это нашел?

Я пошел в консоль GCP, хранилище. Находим загруженный файл. Нажал "Копировать URL".

Вы можете сначала сделать файл общедоступным. У меня так получилось:

const bucket = seFirebaseService.admin().storage().bucket()
await bucket.file(`public/myFile.png`).makePublic()

Я возился с этим несколько дней и понял

A) правильные права доступа к корзине являются ключевыми:

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

Б) Функциональный общедоступный URL-адрес находится прямо в метаданных (протестирован и работает). Обратите внимание на права доступа.

        const pdfDoc = printer.createPdfKitDocument(docDefinition);
  const pdfFile = admin
      .storage()
      .bucket()
      .file(newId + '.pdf');

    pdfDoc.pipe(
      pdfFile.createWriteStream({
        contentType: 'application/pdf',
        public: true,
      })
    );
    pdfDoc.end();

    console.log('Get public URL');
    const publicUrl = pdfFile.metadata.mediaLink;

просто не загружайте изображение ни в какие пути / папки, просто загрузите его на улицу и измените правила

Другие вопросы по тегам