Firebase cloud functions - observe ref - firebase

I´m completely new to firebase cloud functions. I want to refer to different refs inside a cloud function and get an array with the values of these.
So for example I want to get all the fruits from ('fruits').
similar to (IOS):
ref.observe(.childAdded ... )
How do I code that?

There is currently no way to only trigger a Cloud Function when a new child node is added. Instead you will have to trigger for every write (with onWrite()) and then filter inside the code.
The Firebase documentation on using previous values has this example:
exports.makeUppercase = functions.database.ref('/messages/{pushId}/original')
.onWrite(event => {
// Only edit data when it is first created.
if (event.data.previous.exists()) {
return;
}
// Exit when the data is deleted.
if (!event.data.exists()) {
return;
}
...
Hmmm.... on second reading of your question, you may be looking how to read from other parts of your database inside a Cloud Function. For that you'd use the Firebase Admin SDK, of which you can find an example in this sample in the functions-samples repo:
admin.database().ref('/messages').push({original: original}).then(snapshot => {
...
})

Related

Been trying to set Custom time on a file using Firebase?

I'm trying to set the Custom time attribute in firebase on the front end. Everything is possible to set, like contentDisposition, custom Metadata etc, just can't find any way or any info about setting Custom time.
You can see it referenced here https://cloud.google.com/storage/docs/metadata#custom-time
You can set the custom time on the file manually in the Storage cloud console, but even when you do and you load the file in firebase on the front end, it's missing from the returned object! (makes me feel like it's not possible to achieve this)
var storage = this.$firebase.app().storage("gs://my-files");
var storage2 = storage.ref().child(this.file);
//// Tried this
var md = {
customTime: now.$firebase.firestore.FieldValue.serverTimestamp()
};
//// & Tried this
var md = {
Custom-Time: now.$firebase.firestore.FieldValue.serverTimestamp()
};
storage2.updateMetadata(md).then((metadata) => {
console.log(metadata);
}).catch((err) => {
console.log(err);
});
The reason I ask is I'm trying to push back the lifecycle delete date (which will be based on the custom time) every time the file is loaded. Does anyone know the answer or an alternative way of doing it?
Thanks in advance
The CustomTime metadata is not possible to update using Firebase JavaScript SDK since it is not included in the file metadata properties list mentioned in the documentation. So even if you specify it as customTime: or Custom-Time: the updateMetadata() method does not perform any changes.
I suggest you as a better practice, set the CustomTime metadata from the cloud console and modify the CustomTimeBefore Lifecycle condition from the back-end each time you load the file using the addLifeCycleRule method of the GCP Node.js Client.
// Imports the Google Cloud client library
const {Storage} = require('#google-cloud/storage');
// Creates a client
const storage = new Storage();
//Imports your Google Cloud Storage bucket
const myBucket = storage.bucket('my_bucket');
//-
// Delete object that has a customTime before 2021-05-25.
//-
myBucket.addLifecycleRule({
action: 'delete',
condition: {
customTimeBefore: new Date('2021-05-25')
}
}, function(err, apiResponse) {});

How can I push a JSON to firebase realtime database from cloud functions?

So I am very new to Firebase and also this is the first time I use TypeScript (no JavaScript experience either), and here is what I try to do. I have a JSON structure that I want my cloud function to add to database every time some action happens. My question is the following - could you point me to the right direction, on where I can get info besides official documentation, maybe some code examples would be great. Here is the JSON format I want to push to database. I want this to appear just like Firebase structures data in the console, nested nodes etc.
{
'Player': {
'id':'name',
'visible': {
'place': 'a1',
'sign': 'rock'
}
}
}
In your cloud function, you can use code like this to update the database:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
// In your function
//##########################################
var playerRef = admin.database().ref('/Player');
// You can group multiple updates in an object
var updates = {};
updates['id'] = 'name';
updates['visible'] = {
place: 'a1',
sign: 'rock'
};
// Make sure to return the promise
return playerRef.update(updates);
//##########################################

Cloud Functions retrieve List from Firebase Database

I'm triggering a Cloud Function using Http Request.
The issue is to retrieve the entire List of Objects I have, without an event to then loop through them.
The List is under the account/userId Node.
Here is what I use but I get nothing:
return admin.database().ref('/account/' + userId).once('value').then(function (snap) {
let data = snap.val();
}
Without seeing your database structure it is a bit difficult to write an answer and be 100% sure it is a correct one, but the following should do the trick:
return admin.database().ref('/account/' + userId).once('value').then(function (snap)
snap.forEach(function(child) {
const childKey = child.key; // <- here you get the key of each child of the '/account/' + userId node
console.log(childKey);
const childVal = child.val(); // <- and here you get the values of these children as JavaScript objects
console.log(childVal);
});
});
In case this is not exactly what you are looking for, please update you Question with your database structure and the entire code of your Cloud Function.

Cloud Functions database event always contains empty data

I have an issue with my cloud functions where in all my database events all return empty. For example, in the following event the event.data.val() would return null. I am doing an update operation and have tested the update by testing the cloud function using the shell as well as after deploying.
export const createSubscription = functions.database.ref('/users/{userId}/subscription').onWrite( event => {
if(!event.data.val()) {
return;
}
});
But I can easily hook into the auth.user() events like the following and receive the data.
export const createStripeUser = functions.auth.user().onCreate(event => {
const user = event.data;
});
Edit: Passing data into the collection for example like the one below on the emulator console
createSubscription({
testKey: 'testValue'
})
or the following on from my frontend
db.ref(`/users/23213213213/subscription`).update({ testKey: 'testValue'});
would return null on the function.
DougStevenson is correct. For the .onCreate() you would be doing it correct wit a myDatabaseFunction('new_data').
With the .onWrite() you need to pass in the before and after like my example below.
You may have got stuck were I did. Note that I have a curly bracket around the before and after the final JSON. It didn't work properly without them.
addComment({before: {"comment":"before comment","role":"guest"}, after:{"comment":"After Comment","role":"guest"}})
Hope my example helps a bit more than a generic string parameter.
Good Luck!

Cloud Functions for Firebase: onWrite() executed without new data

I use Cloud Functions for Firebase for some server-side-tasks. Using the database-trigger onWrite() I experience some unexpected behaviour.
exports.doStuff = functions.database.ref('/topic/{topicId}/new').onWrite((event) => {
// If data, then continue...
if (event.data.val()){
// doStuff
//
} else {
console.log("started, but no content!");
}
When new data is added to the specified folder the function is started at least once without any new content ("started, but no content!" is logged to the console). Sometimes even two, three or four times. Then it's run again, automatically (a couple of seconds later) and this time everything works as expected.
EDIT:
The code that writes to the specified node is as follows:
functionA(topicId){
return this.db.object('/topic/'+topicId+'/new').update({
timestamp: firebase.database.ServerValue.TIMESTAMP
});
}
The timestamp is only set once. So before that operation is called, the node new does not exist. So there is no edit or delete. However, this means, by calling the above function first the node new is created, some miliseconds later timestamp and then the value for timestamp. Does Firebase call the onWrite() function for each of these events?
Does this make sense to anybody? Any idea how to make sure, that the function is only executed, when there is really new data available?
onWrite() has a new format, since version 1.0 of Firebase SDK
Your original code was based on tutorials or help from an earlier, beta, version of Firebase.
exports.doStuff = functions.database.ref('/topic/{topicId}/new')
.onWrite((event) => {
if (event.data.val()){
// do stuff
}
}
However since version 1.0, the first parameter in the onWrite function is a "change" object which has two properties: before and after. You want the after. You can get it as follows:
exports.doStuff = functions.database.ref('/topic/{topicId}/new')
.onWrite((change) => {
if (change.after.val()){
// do stuff
}
}
Source: https://firebase.google.com/docs/reference/functions/functions.Change

Resources