6

I need to send iOS push notifications to user whenever a certain child is added to a Firebase path.

I was thinking, that the best way to do that, would be to make a Node.js worker on Heroku, that would listen for changes and send a notification using Urban Airship.

I'm not sure what the best way is to listen for changes on Firebase from a Node.js worker on Heroku is. I'm not that familiar with heroku workers and Node.js.

Can anyone give me some pointers? Examples?

David East
  • 31,526
  • 6
  • 67
  • 82
Holger Sindbaek
  • 2,278
  • 6
  • 41
  • 68
  • 1
    How about a queue system: push notification objects to a location that's watched by the server, and use transactions to process then remove them. See https://github.com/firebase/firebase-work-queue for a sample implementation. – sbolel Feb 24 '15 at 06:43
  • Interesting. I'll look into it. – Holger Sindbaek Feb 24 '15 at 16:54
  • Here is a relevant question I thought was cool http://stackoverflow.com/questions/28617476/how-to-mitigate-against-long-startup-times-in-firebase-workers-when-dataset-gets – sbolel Feb 25 '15 at 20:36

1 Answers1

4

Sending push notifications with Firebase and node-apn is easy:

var apn = require("apn");
var Firebase = require("firebase");

// true for production pipeline
var service = new apn.connection({ production: false }); 

// Create a reference to the push notification queue
var pushRef = new Firebase("<your-firebase>.firebaseio.com/notificationQueue");
// listen for items added to the queue
pushRef.on("child_added", function(snapshot) {

    // This location expects a JSON object of:
    // {
    //     "token": String - A user's device token
    //     "message": String - The message to send to the user
    // }
    var notificationData = snapshot.val();
    sendNotification(notificationData);
    snapshot.ref().remove();

});

function sendNotification(notificationData) {
    var notification = new apn.notification();
    // The default ping sound
    notification.sound = "ping.aiff";
    // Your custom message
    notification.alert = notificationData.message;
    // Send the notification to the specific device token
    service.pushNotification(notification, [notificationData.token]);
    // Clean up the connection
    service.shutdown();
}

For hosting this script, you won't be able to use a PaaS like Heroku. They tend to kill idle sockets. Instead you'll have to use a virtual machine.

Google Cloud Platform has a Node.js launcher that works well.

David East
  • 31,526
  • 6
  • 67
  • 82
  • from the line: `".firebaseio.com/notificationQueue"`, what is the "`notifiationQueue`", or is that just the reference to listen for changes in Firebase? Also on your second note, referncing: "Google Cloud Platform has a Node.js launcher that works well.", why not use Firebase hosting? – Sauron Feb 26 '16 at 13:36
  • 1. Yes, that's how you listen to when push notifications need to be sent to the specific device. 2. Firebase Hosting is for static assets only, so no server processes. – David East Feb 26 '16 at 14:13
  • ok, then this will solve my problem. I was following the tutorial: https://cloud.google.com/solutions/mobile/firebase-app-engine-android-studio and using servlets in app engine, but it was not listening to firebase node in real-time as the app engine socket kept closing...., and it could only be scheduled given the `cron.xml` file. Very disappointing... – Sauron Feb 26 '16 at 14:16
  • Will using node.js solve the problem I outlined above? I had the question posted here: http://stackoverflow.com/questions/35643730/how-to-keep-app-engine-servlet-listening-to-firebase – Sauron Feb 26 '16 at 16:32
  • Lastly, is your example aligned for non-blocking? – Sauron Feb 26 '16 at 19:12
  • That would send notifications every time your server restarts (for god knows what reason) or when you start the first time it would send a notification for each existing message. – Rodrigo Ruiz Jun 02 '16 at 02:31