1
votes

Google Cloud Storage `predefinedAcl` et` file.makePublic () `ne fonctionnent pas

J'essaie d'obtenir des URL de téléchargement permanentes lorsque je télécharge des fichiers sur Firebase Storage (Google Cloud Storage) à partir de Firebase Cloud Functions (Google Cloud Functions).

J'ai essayé de définir predefinedAcl sur authenticatedRead et à publicRead . Les deux ont entraîné des erreurs 403 (Interdit) lorsque mon application a essayé de télécharger les fichiers. Cela provient de la documentation de CreateWriteStreamOptions . Voici le code:

{ Error: No such object: languagetwo-cd94d.appspot.com/Audio/English/United_States-Allison-Female-IBM/warblers.mp3

Ce code s'exécute sans erreur, écrit le fichier dans Storage et transmet l'URL de téléchargement à la fonction suivante. Lorsque j'essaye de télécharger le fichier avec cette URL:

const {Storage} = require('@google-cloud/storage');
const storage = new Storage({ projectId: 'languagetwo-cd94d' });
const myBucket = storage.bucket('languagetwo-cd94d.appspot.com');

var mp3Promise = new Promise(function(resolve, reject) {
      let options = {
        metadata: {
          contentType: 'audio/mp3'
        }
      };

      synthesizeParams.accept = 'audio/mp3';
      var file = myBucket.file('Audio/' + longLanguage + '/' + pronunciation + '/' + word + '.mp3');
      textToSpeech.synthesize(synthesizeParams)
      .then(function(audio) {
        audio.pipe(file.createWriteStream(options));
      })
      .then(function() {
        file.makePublic()
        .then(function(data) {
          console.log(data)
          resolve('http://storage.googleapis.com/languagetwo-cd94d.appspot.com/Audio/' + longLanguage + '/' + pronunciation + '/' + word + '.mp3');
        })
        .catch(error => console.error(error));
      })
      .catch(error => console.error(error));
    });

J'obtiens cette erreur:

let options = {
        metadata: {
          contentType: 'audio/webm',
          predefinedAcl: 'publicRead'
        }
      };

Téléchargement du fichier depuis mon application (en tant qu'utilisateur autorisé) j'obtiens le message d'erreur 403 (Interdit) .

J'ai également essayé cette propriété, avec le même résultat:

XXX

En continuant, j'ai essayé file.makePublic():

<Error>
<Code>AccessDenied</Code>
<Message>Access denied.</Message>
<Details>
Anonymous caller does not have storage.objects.get access to languagetwo-cd94d.appspot.com/Audio/English/United_States-Allison-Female-IBM/catbirds.mp3.
</Details>
</Error>

Ce code ne s'est même pas exécuté . Il s'est écrasé à file.makePublic () et le message d'erreur était

http://storage.googleapis.com/languagetwo-cd94d.appspot.com/Audio/English/United_States-Allison-Female-IBM/catbirds.mp3

Je ne suis pas sûr de la signification de cette erreur. Je suppose que file.createWriteStream () a écrit dans un emplacement de fichier, puis file.makePublic () n'a pas pu trouver cet emplacement de fichier.

J'ai trouvé les autorisations pour warblers.mp3 sur le navigateur Cloud Storage:

entrez la description de l'image ici


0 commentaires

3 Réponses :


2
votes

la première erreur est due aux autorisations d'accès au bucket, dans le lien, vous pouvez trouvez les instructions relatives à l'identité et à la Gestion des accès (IAM) . les rôles et l'autorisation de gérer l'accès au bucket.

La deuxième erreur pourrait être une conséquence de la première.

Veuillez me faire savoir si les informations vous conviennent.


4 commentaires

Merci, la documentation contient beaucoup d'informations. J'ai mes règles de stockage Firebase définies pour que les utilisateurs authentifiés lisent tout: allow read: if request.auth! = Null; . La documentation semble dire que la configuration de predefinedAcl: 'authenticatedRead' lors du téléchargement d'un objet fera pour un fichier ce que j'ai défini pour l'ensemble de la base de données, c'est-à-dire qu'il n'y a aucune raison pour moi de définir cette propriété lors des téléchargements. J'obtiens l'erreur 403 d'une connexion authentifiée, donc ce n'est pas ce qui cause l'erreur. Je ne sais pas pourquoi makePublic () ne fonctionne pas, cela entraînerait probablement la même erreur.


J'ai essayé de changer mes règles de stockage Firebase en lecture publique allow: read; et j'obtiens le même message d'erreur, Accès refusé. L'appelant anonyme n'a pas d'accès à storage.objects.get ... Cela suggère que makePublic () ne ferait pas fonctionner ces URL de téléchargement, le problème n'est pas que les fichiers ne sont pas ' t public.


Salut Thomas, eh bien ce problème semble être lié aux autorisations du bucket, vous devez déclarer comme public les objets ou fichiers dans le bucket, pour ce faire, vous pouvez suivre les étapes dans le lien [1], il est décrit la peut rendre un objet public et comment obtenir l'URL pour le partager. [1] cloud.google.com/storage/docs/access -contrôle / rendre-les-données-‌ publiques


Intéressant que le menu sur Google Cloud diffère alors de celui sur Firebase. Laquelle est la source d'or de la vérité? En essayant les étapes, j'obtiens simplement une erreur intitulée «Échec de la mise à jour de la stratégie IAM» «Erreur de backend» lors de la tentative d'enregistrement du rôle allUser / reader. Se sent floconneux comme l'enfer



1
votes

Vous devez modifier les options pour ceci:

let options = {
    public: true,
    metadata: {
      contentType: 'audio/mp3'           
    }
};

https://googleapis.dev/nodejs/storage/latest/global.html#CreateWriteStreamOptions


0 commentaires

0
votes

Je lutte avec le même problème depuis un certain temps et à la fin, voici ce qui l'a résolu pour moi:

const stream = file.createWriteStream(options)
audio.pipe(stream)
stream.on('finish', () => {
  // file APIs will now work
})

Le problème est que audio.pipe (fichier .createWriteStream (options)) crée un flux qui écrit dans le fichier de manière asyncronale. Au moment où vous appelez file.makePublic () , il n'y a aucune garantie que ce flux d'écriture soit terminé.


0 commentaires