Google Cloud Function - Why Bucket Always Returns Empty Array Of Files?
Solution 1:
First and main problem I had was connecting with my Google Cloud Service, this means:
- I generated a brand new private key from Firebase Admin
Downloaded file and settle on my project as my new
Key.json
Then comes the trickiest part. According to Google's documentation
You can use the bucket references returned by the Admin SDK in conjunction with the official Google Cloud Storage client libraries to upload, download, and modify content in the buckets associated with your Firebase projects. Note that you do not have to authenticate Google Cloud Storage libraries when using the Firebase Admin SDK. The bucket references returned by the Admin SDK are already authenticated with the credentials used to initialize your Firebase app.
This means, if you are running you service locally (npm run shell
), you need to instantiate your firebase-admin
.
var serviceAccount = require("./key.json");
var admin = require("firebase-admin");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://<my_project>.firebaseio.com"
});
and then calling
const bucket = admin.storage().bucket('<my_bucket>.appspot.com')
you will be ready to access your files. When accessing your google functions directly through deployment or from cloud console, then accessing your storage wouldn't require an admin
initialization or the key itself such as the first exposed index.js
on the question, turning the code only into something like
const {Storage} = require('@google-cloud/storage');
...
const storage = newStorage({
projectId: '<my_id>',
});
const bucket = storage.bucket('<my_bucket>')
...
Regarding what Mayeru
said:
you have specified the directory as "/images" but instead it should be "images/"
"images/"
could be used for querying prefix
parameters, not directory
. This example shows how it works, like its reference to google's documentation as well.
The following code, with some promise tweaks and parsing JSON data for Android, works like a charm. Locally and remotely.
index.js
var serviceAccount = require("./key.json");
const functions = require('firebase-functions');
const images = require('./images.js');
var admin = require("firebase-admin");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://<my_project>.firebaseio.com"
});
const bucket = admin.storage().bucket('<my_bucket>.appspot.com')
exports.getImages = functions.https.onRequest((request, response) => {
images.getImages(bucket)
.then(urls => response.status(200).send({ data: { urls } }))
.catch(err =>console.error(err));
})
images.js
module.exports = {
getImages
}
const query = {
directory: 'images'
};
functiongetImages(bucket) {
return bucket.getFiles(query)
.then(response =>getUrls(response))
.catch(err =>console.error(err));
}
functiongetUrls(response) {
const promises = []
response.forEach( files => {
files.forEach (file => {
promises.push(getSignedUrl(file));
});
});
returnPromise.all(promises).then(result =>getParsedUrls(result));
}
functiongetSignedUrl(file) {
return file.getSignedUrl({
action: 'read',
expires: '09-01-2019'
})
}
functiongetParsedUrls(result) {
returnJSON.stringify(result.map(mediaLink =>createMedia(mediaLink)));
}
functioncreateMedia(mediaLink) {
const reference = {};
reference.mediaLink = mediaLink[0];
return reference;
}
This will for sure list all the files under images
folder from your bucket and access their signed download urls to be rendered with libraries like Fresco
. Last, but not least, the download URL will be exposed, but to make a GET
request directly on it will require adjustment on your bucket permissions. Anyway, this "permissions thing" is another topic which you might find how to do it also here on stack overflow.
Solution 2:
The logs show:
[[]] // this is the "files" you retrieved.
Files failure
As you can see, you are not retrieving any file, hence why it fails the call to get URLs from empty array.
you have specified the directory as "/images" but instead it should be "images/"
That should be able to retrieved the proper folder.
Also, the function "getDownloadURL()" don't appear as supported for "file" objects on nodejs lib documentation. You might be looking for getSignedUrl ?
Post a Comment for "Google Cloud Function - Why Bucket Always Returns Empty Array Of Files?"