Categories
android android-things firebase

Electricity Monitoring App – Send Push Notifications using Firebase Cloud Functions

This week Firebase launched a new and VERY exciting feature called Firebase Cloud Functions. It makes Firebase even more powerful than before, by allowing you to trigger functions when certain events happen. Events can be any of the following things:

  • Data changes on Firebase Realtime database nodes.
  • Authentication Changes
  • Analytics Changes
  • Cloud Storage Changes
  • and a few more…

Cloud Functions is a hosted, private, and scalable Node.js environment where you can run JavaScript code.

This is exactly what we needed in order to make the Electricity Monitoring App even more useful. By using Firebase Cloud Functions, we can send push notifications when the electricity is off and when it comes back on. Now we don’t need to keep checking the app for changes to our electricity state at home.

Sending a Push Notification Using Firebase Cloud Functions

The following is a diagram that indicates how this solution will work.Firebase cloud function with push notifications

The Raspberry Pi (or any other Android Things device) will write to the /online node in our Realtime Database when the state of electricity changes. Once that has happened the Cloud Function will be triggered, as it is listening for any changes on that node. If the data has changed, for instance the value of /online is now true instead of false, we can trigger a push notification to be sent to all devices that are registered for the “Power_Notifications”  topic using the Firebase Admin SDK

Setup and Deployment of the Firebase Cloud Function

You will need to ensure you have NodeJS installed as well as NPM. Make sure you have followed my previous blog post in order to get the Raspberry Pi app and the companion app running. This post only covers the cloud function changes.

  1. Install Firebase CLI tools:
    npm install -g firebase-tools
  2. Initialize the required dependencies by navigating into the cloud-functions  folder:
    cd cloud-functions 
    npm install
  3. Log in with Firebase (this will prompt you to log in using a browser):
    firebase login
  4. Run the following command to deploy the Firebase functions:
    firebase deploy --only functions
  5. You will be able to see the functions appear in the Firebase Console as seen below:
  6. Now run the app on the Pi and the companion app on your phone (make sure to update this to the latest version as there have been changes). When you disconnect your device from its power source, you will get a notification like below indicating your power is on or off! 

In the next section we will discuss how the Firebase Cloud Function was implemented. If you want to see how this is done, read on – otherwise Happy Electricity Monitoring!

Developing Firebase Cloud Function Triggers

So how did we send a push notification? The full code for the firebase cloud function can be found in this repository but we can cover the basics here:

  1. We require the firebase-functions npm package in order to create a Firebase function. The firebase-admin npm package is required for us to send notifications. The admin SDK needs to be initialized with the functions configuration.
    const functions = require('firebase-functions');
    const admin = require('firebase-admin');
    admin.initializeApp(functions.config().firebase);
  2. Export a function by the name of sendPowerNotification. This name will be visible on the Cloud Functions tab in the Firebase console, so call it something useful. Obtain a reference to the database node /online. We want to watch for changes on this node. Use the function onWrite which will trigger when a write event happens.
    exports.sendPowerNotification = functions.database.ref("/online").onWrite((event) => {
        
    });
  3. When the onWrite event is triggered, an event object is passed with the updated information. This object can indicate if anything has changed by calling the method data.changed(). If nothing has changed, we abort the function.
    exports.sendPowerNotification = functions.database.ref("/online").onWrite((event) => {
        const data = event.data;
        console.log('Power event triggered');
        if (!data.changed()) {
            return;
        }
       //..
    });

Sending a Push Notification using Firebase Messaging

  1. Check the value of the data object. If it is true or false we adjust the title of the notification that we are going to send accordingly.
    exports.sendPowerNotification = functions.database.ref("/online").onWrite((event) => {
        const data = event.data;
        console.log('Power event triggered');
        if (!data.changed()) {
            return;
        }
        const status = data.val();
        const onOff =  status ? "on": "off";
    
      //..
    });
  2. Create a payload object that has the required information for a Firebase Notification (title, message, sound etc). Then create an options object that contains the time to live for the notification and the priority.
    exports.sendPowerNotification = functions.database.ref("/online").onWrite((event) => {
        //..
        const status = data.val();
        const onOff =  status ? "on": "off";
    
        const payload = {
            notification: {
                title: 'Electricity Monitor - Power status changed',
                body: `Your electricity is now ${onOff}`,
                sound: "default"
            }
        };
    
        const options = {
            priority: "high",
            timeToLive: 60 * 60 * 24 //24 hours
        };
        //..
    });
  3. Finally, call the Firebase Admin Messaging SDK by using the sendToTopic() method with the above information. This will send a push notification to all devices that are registered to the “Power_Notifications” topic.
    exports.sendPowerNotification = functions.database.ref("/online").onWrite((event) => {
        //..
        return admin.messaging().sendToTopic("Power_Notifications", payload, options);
    });

    The full source for this function can be found here.

Android Companion App Code Changes

The following changes were made to the Android Companion app:

  1. Adding the Firebase Messaging SDK to app/build.gradle:
     compile 'com.google.firebase:firebase-messaging:<latest-version>'
  2. Register the “Power_Notifications” topic in the ElectricityApplication class.
    public class ElectricityApplication extends Application {
        @Override
        public void onCreate() {
            super.onCreate();
            //.. other init code
            FirebaseApp.initializeApp(this);
            FirebaseMessaging.getInstance().subscribeToTopic("Power_Notifications");
        }
    }
  3. Change the push notification icon in the AndroidManifest.xml to the power icon found here:
    <meta-data
                android:name="com.google.firebase.messaging.default_notification_icon"
                android:resource="@drawable/ic_power" />

    After these changes are all made, you will be able to receive notification updates about your electricity at home!

Conclusion

Firebase Cloud Functions are extremely powerful pieces of code that can do a lot of heavy lifting for you.  Firebase manages the hosting and scaling of the functions.

As you can see from the above example, it wasn’t too much work to send push notifications from Firebase Cloud Functions.

If you enjoyed this blog post, please consider buying me a cupcake. Follow me on twitter @riggaroo and let me know what you think there.

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

References

Firebase Cloud Functions Documentation

Android Things – Electricity Monitoring App – Github

Previous Blog Post describing Android Things setup

Firebase Cloud Functions Examples