Writing a Realtime Database Trigger with Cloud Functions for Firebase - Firecasts

By: Firebase

429   9   27220

Uploaded on 04/18/2017

Documentation: https://goo.gl/F68S1L
Codelab: https://goo.gl/4ddrHv
Sample code: https://goo.gl/UQWJzb

Cloud Functions for Firebase lets you run managed backend code for your mobile app that extends and connects Firebase features. In this Firecast, Jen will show you how to write a function that triggers in response to a write to the Realtime Database.

Add the Firecasts playlist! https://goo.gl/n2XqG1

Subscribe to the Firebase Channel: https://goo.gl/9giPHG

Music by http://terramonk.com

Comments (10):

By anonymous    2017-09-20

I see that you've also asked this question in the comments for my Firecast on YouTube. That's a good question. If you've been following along with the Cloud Functions for Firebase samples, you might have seen admin.database().ref().

admin.database().ref() uses the Firebase admin SDK to access data in the Database. As an admin reference, it has unrestricted access to any part of the Database.

In the video, root = event.data.ref.root, a reference to the root of the database where the .onWrite event occurred. ref has the same read and write access as the user who triggered the event. Unlike admin.database().ref(), it does not grant unrestricted access. root.child therefore access that specific path in the database, as long as the user has permission to access it.

Now event.data.adminRef.root is a Database reference with unrestricted access to any part of the Database. If this sounds like admin.database.ref(), it's because they're exactly alike. In my case, I chose event.data.ref.root to limit the amount of new topics introduced in one video. If you're more comfortable using the admin SDK, that is totally fine.

Original Thread

By anonymous    2017-09-20

I agree that you won't want to do all that work client-side! Cloud Functions for Firebase are a good option. You can trigger a function on a write to a path in the database, and then make the change to the other related paths. Check out these resources to find out more:

Getting Started with Cloud Functions for Firebase

GitHub samples

Cloud Functions for Firebase documentation

Writing a Database Trigger

Writing a Cloud Storage Trigger: Part 1

Writing a Cloud Storage Trigger: Part 2

Original Thread

By anonymous    2017-09-20

Alright guys I figured it out myself and I will write a mini tutorial here.

Because this question specifically deals with stripe I will only cover this specific use case. First it is important to read the Stripe documentation. It specifies the parameters it is expecting you to give to it's api. Here is the link for what is expected when you charge a card with Stripe: Stripe Charges Documentation

Second you need to model your Firebase Realtime database after those expected parameters, at least in regards to the purchases a user will make in your app. Most of the time you can use a dictionary with Key:value pairs. Make sure you multiply your amount parameter by 100 as Stripe only takes integers. This means if you you are charging 22.48 for example then you multiply it by 100 to get 2248. When you check your dashboard in stripe it will show up as 22.48.

Third Stripe needs to talk to a back end so that you can charge the card. Firebase Cloud functions are perfect for this. Remember your real time database? Well you can trigger a Cloud function when a write occurs on a node that you specify. Luckily Firebase has provided a sample on GitHub: Firebase Stripe Example

You can modify the line of code where it listens for a write to the data base. You can change it to your structure specifically as long as you return at least the token and the amount to be charged. If you are going to make the user enter their information every time, then you need to delete the customer parameter (in the index.js file) as it will expect a different token with a different prefix. (This is noted in the documentation) The rest of the example is well documented and can be followed. The outcome of the charge will be written back into your database. The following video shows you how Functions triggered on write work and some of the nomenclature used. : Youtube Video for Cloud Functions triggered on write.

I hope this helps a few of you as I know questions about stripe and firebase are fairly common.

Original Thread

By anonymous    2017-11-13

I'm developing Server with Firebase.

I had copied Google Developer's Video on Youtube.

It works well, but on log there is an error:

Function returned undefined, expected Promise or value

It says function returned undefined, but I make function return a promise `set``

How can I solve this?

function sanitize(s) {
    var sanitizedText = s;
    console.log('sanitize params: ', sanitizedText);
    sanitizedText = sanitizedText.replace(/\bstupid\b/ig, "wonderful");
    return sanitizedText;
}
exports.sanitizePost = functions.database
    .ref('/posts/{pushId}')
    .onWrite(event => {
        const post = event.data.val();
        if (post.sanitized) return;

        console.log('Sanitizing new post', event.params.pushId);
        console.log(post);
        post.sanitized = true;
        post.title = sanitize(post.title);
        post.body = sanitize(post.body);
        return event.data.ref.set(post); 
    })

I'm beginner of Firebase, Nodejs.

Original Thread

By anonymous    2017-12-18

Finally found the solution after struggling for almost 1 month.

These are the basic steps

  1. Firs off all you need to make sure that you have an active apple developers account

  2. just enable firebase push notifications here ie the link of youtube video for this step

  3. Now your app is set up for firebase remote notifications but we can only trigger them from the firebase console so here is the tricky part. here is the link of video to enable firebase console on your mac
  4. for the first time it will be good to see this video too because in this video they'll learn to write code in node.js and deploy it to the firebase.
  5. Now if anyone wants to make an API instead of making a trigger then here is a code of API which sends the notification to other user by getting his FCM token from the firebase... You can modify it according to your need

i am finding it difficult to post code in its exact form but the code starts from here

const functions = require('firebase-functions');

const admin =require('firebase-admin');
admin.initializeApp(functions.config().firebase);

const ref=admin.database().ref();
exports.sendNotification=functions.https.onRequest((req,res) =>{

    const id = req.query.id
    const title = req.query.title
    const message = req.query.message
    const key = req.query.key
    // admin.database.ref()

    const payload ={

        notification: {
            title: title,
            body: message,
            //badge: '1',
            sound: 'default',
        }
    };

    console.log('Param [key] is '+key);

    const keys = [] ;

    ref.child('keys').once('value')
    .then(snap => {
        snap.forEach(childSnap => {

            const loopKey=childSnap.val().key;
            keys.push(loopKey);

        })

        return keys;
    })
    .then(keys=>{

        //console.log('Keys in database : '+keys.join());

        if(keys.indexOf(key)>-1)
        {
            if(!key || !id || !message)
            {
                res.status(400).send('Bad request');
            }
            else{
                ref.child('users').child(id).child('fcmToken').once('value')
                .then(snapshot => {
                    if (snapshot.val()){
                        const token = snapshot.val()
                        console.log(token);
                        return admin.messaging().sendToDevice(token,payload).then(response =>{
                            res.status(200).send('Notification sent')
                        });
                    }   
                });
            }
        }
        else
        {
            console.log("In-valid key : "+key);

            res.status(400).send('Bad request');
        }   
    })
    .catch(error => {
        res.send(error)
    });

});

ends at this point

this is the function to store your fcm to database

func postToken(token: String, id: String){
    print("FCM Token \(token)")
    let ref = Database.database().reference().child("users").child(id)
    ref.child("fcmToken").setValue(token)
}

here is the function which i used to trigger this API

func sendNotification(id: String, title: String, message: String){
    var url = "your URL"
    var urlComponents = NSURLComponents(string: url)
    urlComponents?.queryItems = [
        URLQueryItem(name: "key", value: self.apiKey),
        URLQueryItem(name: "id", value: id),
        URLQueryItem(name: "title", value: title),
        URLQueryItem(name: "message", value: message)
    ]

    Alamofire.request((urlComponents?.url)!).responseJSON { (response) in
        print(response.response)
        print(response.response)
        print(response.result)
    }

}

the above API was written according to my database structure. you can change it easily for your own structure.

after doing this all you'll be able to send your notifications after hitting the URL

Hope it will give a nice idea to you people to work with your own notifications according to your need.

Original Thread

By anonymous    2018-02-18

Timeouts

First of all, check your Cloud Functions logs to see if you get any timeout messages.

Function execution took 60087 ms, finished with status: 'timeout'

If so, sort out your function so that it returns a Promise.resolve(). And shows

Function execution took 344 ms, finished with status: 'ok'

Idempotency

Secondly, write your data so that the function is idempotent. When your function runs, write a value to the document that you are reading. You can then check if that value exists before running the function again.

See this example for ensuring that functions are only run once.

Original Thread

By anonymous    2018-02-18

It is not possible to carry out any aggregate queries in Cloud Firestore. You will need to find an alternative way to get the totals. There are several options:

  • Query all documents which voted 'yes' and count them in your client app, then do the same for all of the 'no' votes.
  • If you are not likely to receive more than one vote per second, you could create a cloud function which uses a transaction to update a single document. You may need to also write to the original document, to say that it has been counted. Functions need to be idempotent, so you need to ensure that votes aren't counted twice. See this great example.
  • Create a Cloud Function which writes each vote to something like BigQuery and list the votes there.
  • If your needs are more complex, consider piping the data through Dataflow (or other Apache Beam provider)

Original Thread

Popular Videos 127

Submit Your Video

If you have some great dev videos to share, please fill out this form.