Cette réponse résume les options pour obtenir l'URL de téléchargement lors du téléchargement d'un fichier sur Google / Firebase Cloud Storage. Il existe trois types d'URL de téléchargement:
- URL de téléchargement signées, temporaires et dotées de fonctionnalités de sécurité
- URL de téléchargement de jetons, persistantes et dotées de fonctionnalités de sécurité
- URL de téléchargement publiques, qui sont persistantes et manquent de sécurité
Il existe trois façons d'obtenir une URL de téléchargement de jeton. Les deux autres URL de téléchargement n'ont qu'un seul moyen de les obtenir.
Depuis la console de stockage Firebase
Vous pouvez obtenir l'URL de téléchargement depuis la console Firebase Storage:
L'URL de téléchargement ressemble à ceci:
https://firebasestorage.googleapis.com/v0/b/languagetwo-cd94d.appspot.com/o/Audio%2FEnglish%2FUnited_States-OED-0%2Fabout.mp3?alt=media&token=489c48b3-23fb-4270-bd85-0a328d2808e5
La première partie est un chemin standard vers votre fichier. À la fin se trouve le jeton. Cette URL de téléchargement est permanente, c'est-à-dire qu'elle n'expirera pas, bien que vous puissiez la révoquer.
getDownloadURL () depuis le frontal
La documentation nous dit d'utiliser getDownloadURL()
:
let url = await firebase.storage().ref('Audio/English/United_States-OED-' + i +'/' + $scope.word.word + ".mp3").getDownloadURL();
Cela obtient la même URL de téléchargement que celle que vous pouvez obtenir depuis votre console Firebase Storage. Cette méthode est simple mais nécessite que vous connaissiez le chemin d'accès à votre fichier, qui dans mon application compte environ 300 lignes de code, pour une structure de base de données relativement simple. Si votre base de données est complexe, ce serait un cauchemar. Et vous pouvez télécharger des fichiers depuis le frontal, mais cela exposerait vos informations d'identification à quiconque télécharge votre application. Ainsi, pour la plupart des projets, vous voudrez télécharger vos fichiers depuis votre back-end Node ou Google Cloud Functions, puis obtenir l'URL de téléchargement et l'enregistrer dans votre base de données avec d'autres données sur votre fichier.
getSignedUrl () pour les URL de téléchargement temporaires
getSignedUrl () est facile à utiliser à partir d'un back-end Node ou de Google Cloud Functions:
function oedPromise() {
return new Promise(function(resolve, reject) {
http.get(oedAudioURL, function(response) {
response.pipe(file.createWriteStream(options))
.on('error', function(error) {
console.error(error);
reject(error);
})
.on('finish', function() {
file.getSignedUrl(config, function(err, url) {
if (err) {
console.error(err);
return;
} else {
resolve(url);
}
});
});
});
});
}
Une URL de téléchargement signée ressemble à ceci:
https://storage.googleapis.com/languagetwo-cd94d.appspot.com/Audio%2FSpanish%2FLatin_America-Sofia-Female-IBM%2Faqu%C3%AD.mp3?GoogleAccessId=languagetwo-cd94d%40appspot.gserviceaccount.com&Expires=4711305600&Signature=WUmABCZIlUp6eg7dKaBFycuO%2Baz5vOGTl29Je%2BNpselq8JSl7%2BIGG1LnCl0AlrHpxVZLxhk0iiqIejj4Qa6pSMx%2FhuBfZLT2Z%2FQhIzEAoyiZFn8xy%2FrhtymjDcpbDKGZYjmWNONFezMgYekNYHi05EPMoHtiUDsP47xHm3XwW9BcbuW6DaWh2UKrCxERy6cJTJ01H9NK1wCUZSMT0%2BUeNpwTvbRwc4aIqSD3UbXSMQlFMxxWbPvf%2B8Q0nEcaAB1qMKwNhw1ofAxSSaJvUdXeLFNVxsjm2V9HX4Y7OIuWwAxtGedLhgSleOP4ErByvGQCZsoO4nljjF97veil62ilaQ%3D%3D
L'URL signée a une date d'expiration et une signature longue. La documentation de la ligne de commande gsutil signurl -d indique que les URL signées sont temporaires: l'expiration par défaut est d'une heure et l'expiration maximale est de sept jours.
Je vais dénoncer ici que getSignedUrl ne dit jamais que votre URL signée expirera dans une semaine. Le code de documentation a 3-17-2025
comme date d'expiration, ce qui suggère que vous pouvez définir les années d'expiration dans le futur. Mon application a parfaitement fonctionné, puis s'est plantée une semaine plus tard. Le message d'erreur indiquait que les signatures ne correspondaient pas, et non que l'URL de téléchargement avait expiré. J'ai apporté diverses modifications à mon code et tout a fonctionné ... jusqu'à ce que tout se bloque une semaine plus tard. Cela a duré plus d'un mois de frustration.
Rendre votre fichier accessible au public
Vous pouvez définir les autorisations sur votre fichier en lecture publique, comme expliqué dans la documentation . Cela peut être fait à partir du navigateur Cloud Storage ou de votre serveur Node. Vous pouvez rendre un fichier public ou un répertoire ou l'ensemble de votre base de données de stockage. Voici le code du nœud:
var webmPromise = new Promise(function(resolve, reject) {
var options = {
destination: ('Audio/' + longLanguage + '/' + pronunciation + '/' + word + '.mp3'),
predefinedAcl: 'publicRead',
contentType: 'audio/' + audioType,
};
synthesizeParams.accept = 'audio/webm';
var file = bucket.file('Audio/' + longLanguage + '/' + pronunciation + '/' + word + '.webm');
textToSpeech.synthesize(synthesizeParams)
.then(function(audio) {
audio.pipe(file.createWriteStream(options));
})
.then(function() {
console.log("webm audio file written.");
resolve();
})
.catch(error => console.error(error));
});
Le résultat ressemblera à ceci dans votre navigateur Cloud Storage:
Tout le monde peut alors utiliser le chemin standard pour télécharger votre fichier:
https://storage.googleapis.com/languagetwo-cd94d.appspot.com/Audio/English/United_States-OED-0/system.mp3
Une autre façon de rendre un fichier public est d'utiliser la méthode makePublic () . Je n'ai pas été en mesure de faire fonctionner cela, il est difficile d'obtenir le bon chemin de seau et de fichier.
Une alternative intéressante consiste à utiliser les listes de contrôle d'accès . Vous pouvez rendre un fichier disponible uniquement pour les utilisateurs que vous avez mis sur une liste, ou utiliser authenticatedRead
pour rendre le fichier disponible à toute personne qui est connectée à partir d'un compte Google. S'il y avait une option "toute personne qui s'est connectée à mon application en utilisant Firebase Auth", je l'utiliserais, car cela limiterait l'accès à mes utilisateurs uniquement.
Créez votre propre URL de téléchargement avec firebaseStorageDownloadTokens
Plusieurs réponses décrivent une propriété d'objet Google Storage non documentée firebaseStorageDownloadTokens
. Avec cela, vous pouvez indiquer à Storage le jeton que vous souhaitez utiliser. Vous pouvez générer un jeton avec le uuid
module Node. Quatre lignes de code et vous pouvez créer votre propre URL de téléchargement, la même URL de téléchargement que vous obtenez depuis la console ou getDownloadURL()
. Les quatre lignes de code sont:
const uuidv4 = require('uuid/v4');
const uuid = uuidv4();
metadata: { firebaseStorageDownloadTokens: uuid }
https://firebasestorage.googleapis.com/v0/b/" + bucket.name + "/o/" + encodeURIComponent('Audio/' + longLanguage + '/' + pronunciation + '/' + word + '.webm') + "?alt=media&token=" + uuid);
Voici le code en contexte:
var webmPromise = new Promise(function(resolve, reject) {
var options = {
destination: ('Audio/' + longLanguage + '/' + pronunciation + '/' + word + '.mp3'),
contentType: 'audio/' + audioType,
metadata: {
metadata: {
firebaseStorageDownloadTokens: uuid,
}
}
};
synthesizeParams.accept = 'audio/webm';
var file = bucket.file('Audio/' + longLanguage + '/' + pronunciation + '/' + word + '.webm');
textToSpeech.synthesize(synthesizeParams)
.then(function(audio) {
audio.pipe(file.createWriteStream(options));
})
.then(function() {
resolve("https://firebasestorage.googleapis.com/v0/b/" + bucket.name + "/o/" + encodeURIComponent('Audio/' + longLanguage + '/' + pronunciation + '/' + word + '.webm') + "?alt=media&token=" + uuid);
})
.catch(error => console.error(error));
});
Ce n'est pas une faute de frappe - vous devez imbriquer firebaseStorageDownloadTokens
en double couche de metadata:
!
Doug Stevenson a souligné qu'il firebaseStorageDownloadTokens
ne s'agissait pas d'une fonctionnalité officielle de Google Cloud Storage. Vous ne le trouverez dans aucune documentation Google et il n'y a aucune promesse qu'il le sera dans la future version de @google-cloud
. J'aime firebaseStorageDownloadTokens
parce que c'est le seul moyen d'obtenir ce que je veux, mais il a une "odeur" qui n'est pas sûre à utiliser.
Pourquoi pas getDownloadURL () de Node?
Comme @Clinton l'a écrit, Google devrait créer une file.getDownloadURL()
méthode dans @google-cloud/storage
(c'est- à -dire, votre back-end Node). Je souhaite importer un fichier depuis Google Cloud Functions et obtenir l'URL de téléchargement du jeton.