Obtenez L'URL de téléchargement du fichier chargé avec des fonctions Cloud pour Firebase
après avoir téléchargé un fichier dans le stockage Firebase avec des fonctions pour Firebase, je voudrais obtenir l'url de téléchargement du fichier.
j'ai ceci :
...
return bucket
.upload(fromFilePath, {destination: toFilePath})
.then((err, file) => {
// Get the download url of file
});
le fichier objet a beaucoup de paramètres. Même un nommé mediaLink
. Cependant, si j'essaie d'accéder à ce lien, j'obtiens cette erreur :
<!-Est-ce que quelqu'un peut me dire comment obtenir le téléchargement public Url?utilisateurs Anonymes n'ont pas de stockage.objet.obtenez de l'accès à l'objet ...
Merci
10 réponses
vous devrez générer une URL signée en utilisant getSignedURL via le @google-cloud/stockage NPM module.
Exemple:
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
});
Vous aurez besoin d'initialiser @google-cloud/storage
vos justificatifs d'identité de compte de service étant donné que les justificatifs d'identité par défaut ne seront pas suffisants.
UPDATE: le SDK de stockage Cloud est maintenant accessible via le SDK Admin Firebase, qui agit comme un wrapper autour de @google-cloud/stockage. Vous devrez tout de même initialiser le SDK avec un compte de service, généralement par l'intermédiaire d'une deuxième instance, non par défaut.
voici un exemple sur la façon de spécifier le token de téléchargement lors du téléchargement:
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);
});
}
ensuite appeler
upload(localPath, remotePath).then( downloadURL => {
console.log(downloadURL);
});
la chose clé ici est qu'il y a un metadata
objet imbriqué dans le metadata
propriété option. Réglage firebaseStorageDownloadTokens
à une valeur uuid-v4 indiquera à Cloud Storage de l'utiliser comme son token d'autorisation publique.
Merci beaucoup à @martemorfosis
une méthode que j'utilise avec succès est de définir une valeur UUID v4 à une clé nommée firebaseStorageDownloadTokens
dans les métadonnées du fichier après qu'il a terminé le téléchargement et puis assembler L'URL de téléchargement moi-même en suivant la structure Firebase utilise pour générer ces URLs, par exemple:
https://firebasestorage.googleapis.com/v0/b/[BUCKET_NAME]/o/[FILE_PATH]?alt=media&token=[THE_TOKEN_YOU_CREATED]
Je ne sais pas combien "sûr" est d'utiliser cette méthode (étant donné que Firebase pourrait changer la façon dont il génère les URLs de téléchargement dans le futur ) mais il est facile à mettre en œuvre.
For those wondering where the Firebase Admin SDKSERVICEACCOUNTKEY.le dossier json devrait partir. Il suffit de le placer dans le dossier fonctions et de les déployer comme d'habitude.
il me déconcerte encore pourquoi nous ne pouvons pas simplement obtenir l'url de téléchargement à partir des métadonnées comme nous le faisons dans le SDK Javascript. Générer une url qui finira par expirer et la sauvegarder dans la base de données n'est pas souhaitable.
Avec les récents changements dans les fonctions objet réponse, vous pouvez obtenir tout ce dont vous avez besoin pour "piquer" ensemble, l'URL de téléchargement comme suit:
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);
désolé mais je ne peux pas poster un commentaire à votre question ci-dessus en raison de la réputation manquante, donc je l'inclurai dans cette réponse.
faire comme indiqué ci-dessus en générant une Url signée, mais au lieu d'utiliser le compte de service.json je pense que vous devez utiliser le serviceAccountKey.json que vous pouvez générer à (remplacer VOTREPROJETTID par conséquent)
https://console.firebase.google.com/project/YOURPROJECTID/settings/serviceaccounts/adminsdk
Exemple:
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
})
je suggère d'utiliser l'option predefinedAcl: 'publicRead'
lors du téléchargement d'un fichier avec Stockage Dans Le Cloud NodeJS 1.6.x:
const options = {
destination: yourFileDestination,
predefinedAcl: 'publicRead'
};
bucket.upload(attachment, options);
alors, obtenir L'URL publique est aussi simple que:
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);
});
cela fonctionne si vous avez juste besoin d'un fichier public avec une URL simple. Notez que cela peut annuler les règles de stockage de la base de données.
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);
}
});
Je ne peux pas commenter la réponse de James Daniels, mais je pense que c'est très Important à lire.
donner une URL signée comme il l'a fait semble pour beaucoup de cas assez mauvais et possible Dangereux. Selon la documentation de Firebase l'url signée expire après un certain temps, donc en ajoutant cela à votre base de données vous obtiendrez une url vide après un certain délai
il se peut que vous ayez mal compris la Documentation et l'url signée. ça n'expire pas, ce qui aurait des problèmes de sécurité. La Clé semble être la même pour chaque fichier téléchargé. Cela signifie qu'une fois que vous avez l'url d'un fichier, quelqu'un pourrait facilement accéder aux fichiers qu'il n'est pas censé accéder, simplement en connaissant leurs noms.
si je n'avais pas compris, j'aurais dû être corrigé. Sinon, quelqu'un devrait probablement mettre à jour la solution susmentionnée. Si j'ai peut-être tort, il y a
pour ceux qui utilisent Firebase SDK etadmin.initializeApp
:
1 - générer une clé privée et le placer dans /dossier fonctions.
2 - Configurez votre code comme suit:
const serviceAccount = require('../../serviceAccountKey.json');
try { admin.initializeApp(Object.assign(functions.config().firebase, { credential: admin.credential.cert(serviceAccount) })); } catch (e) {}
Le try/catch est parce que je suis à l'aide d'un index.js que les importations d'autres fichiers et crée une fonction pour chaque fichier. Si vous utilisez un seul index.fichier js avec toutes les fonctions, vous devriez être ok avec admin.initializeApp(Object.assign(functions.config().firebase, { credential: admin.credential.cert(serviceAccount) }));
.