Showing posts with label Firebase Cloud Messaging. Show all posts
Showing posts with label Firebase Cloud Messaging. Show all posts

Wednesday, 29 March 2017

Using Firebase Cloud Messaging with Android O

Diego Giorgini
Diego Giorgini
Software Engineer


Firebase Cloud Messaging (FCM) is a cross-platform messaging solution that lets you reliably deliver messages to your apps and sites. It provides two types of messages:
  1. Notification Messages display a simple notification popup, with optional data payload.
  2. Data Messages deliver a JSON payload to your application and let your code handle it.
Data Messages are a great way to build custom notifications, when the layout provided by notification messages is not enough, or to trigger background operations like a database sync or the download of additional content (image attachments, emails, etc.)

How should Data Messages trigger background operations?

The best way to trigger a background operation from a data message is by using Firebase Job Dispatcher to take advantage of the Android JobScheduler and Google Play services API.

By using Firebase Job Dispatcher you allow the operating system to schedule your operation when it's best for the user (like avoiding extra work when the battery is very low, or when the CPU is already heavily used by other foreground applications). Firebase Job Dispatcher also guarantees that your background task will be performed, and not killed by the system when foreground applications require more resources.

Background Process Optimizations in Android O

To get started, check out the Android O Developer Preview site where you will find instructions on downloading and installing the required SDKs. For Firebase Development, you'll also need to install the Firebase SDKs for Android. Be sure to use version 10.2.1 or later for Android O development.

Android O introduces new background processes optimizations, which make the use of JobScheduler (or wrapper libraries like Firebase Job Dispatcher) a requirement for long-running background operations. Due to these optimizations, the FCM (hence GCM as well) callbacks onMessageReceived()and onTokenRefresh() have a guaranteed life cycle limited to 10 seconds (same as a Broadcast Receiver).

After the guaranteed period of 10 seconds, Android considers your process eligible for termination, even if your code is still executing inside the callback.

To avoid your process being terminated before your callback is completed, be sure to perform only quick operations (like updating a local database, or displaying a custom notification) inside the callback, and use JobScheduler to schedule longer background processes (like downloading additional images or syncing the database with a remote source).
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
if (/* Check if data needs to be processed by long running job */ true) {
// For long-running tasks (10 seconds or more) use Firebase Job Dispatcher.
scheduleJob();
} else {
// Handle message within 10 seconds
handleNow();
}
}
/**
* Schedule a job using FirebaseJobDispatcher.
*/
private void scheduleJob() {
FirebaseJobDispatcher dispatcher =
new FirebaseJobDispatcher(new GooglePlayDriver(this));
Job myJob = dispatcher.newJobBuilder()
.setService(MyJobService.class)
.setTag("my-job-tag")
.build();
dispatcher.mustSchedule(myJob);
}
/**
* Perform and immediate, but quick, processing of the message.
*/
private void handleNow() {
Log.d(TAG, "Short lived task is done.");
}
We hope this helps you understand how to use FCM to schedule long-running background operations. This solution greatly helps Android to preserve battery life and ensures that your application works fine on Android O. In case you have any questions don't hesitate to ask us on our support channels.
Share:

Thursday, 2 February 2017

Firebase Cloud Messaging integrated into the Admin Node.js SDK

Jacob Wenger
Software Engineer
With Firebase, we've been working towards a world where developers don't have to deal with managing servers and can instead build web and mobile apps with only client-side code. However, there are times when you really do need to spin up your own server. Towards that aim, we announcedthe Firebase Admin SDKs this past November.
Today, I'm excited to share two new Admin SDK features:
  • The Node.js SDK now contains an Admin API for sending messages via Firebase Cloud Messaging (FCM).
  • The Java SDK can now be initialized from a set of built-in credentials, making it easier to use, especially on Google infrastructure.
Admin Node.js FCM API
The new Admin Node.js FCM API simplifies the process of sending messages via FCM. There is no extra setup required to use this new API as the existing credential used to authenticate the Node.js SDK handles everything on your behalf. The new API contains methods for sending messages to individual devices, device groups, topics, and conditions.
As an example, let's assume you are building an app for the upcoming Super Bowl and you want to send a notification to anyone subscribed to either the Atlanta Falcons' topic (/topics/falcons) or the New England Patriots' topic (/topics/patriots):
var admin = require("firebase-admin");

// Fetch the service account key JSON file contents
var serviceAccount = require("path/to/serviceAccountKey.json");

// Initialize the app with a service account, granting admin privileges
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://<DATABASE_NAME>.firebaseio.com"
});

// Define who to send the message to
var condition = "'falcons' in topics || 'patriots' in topics";

// Define the message payload
var payload = {
notification: {
title: "Super Bowl LI: Falcons vs. Patriots",
body: "Your team is Super Bowl bound! Get the inside scoop on the big game."
}
};

// Send a message to the condition with the provided payload
admin.messaging.sendToCondition(condition, payload)
.then(function(response) {
console.log("Successfully sent message! Server response:", response);
})
.catch(function(error) {
console.log("Error sending message:", error);
});
You can optionally provide a third option to any of the FCM methods to provide options for the message. For example, since the game is a little under a week away, let's send the message with high priority and give it a time to live of one week:
// condition and payload are the same as above

var options = {
priority: "high",
timeToLive: 60 * 60 * 24 * 7
};

admin.messaging.sendToCondition(condition, payload, options)
.then(function(response) {
console.log("Successfully sent message! Server response:", response);
})
.catch(function(error) {
console.log("Error sending message:", error);
});
This is just a taste of what the new Admin Node.js FCM API allows you to do. See Send Messages for more code samples and detailed documentation.
Admin Java Credential Interface
Since the launch of the Admin SDKs last November, the Node.js SDK has supported several initialization methods while the Java SDK has only allowed initialization via a service account certificate file. As of the latest Admin Java SDK release, both SDKs now provide a full credential interface with some helpful default implementations.
Upgrading to the new API is straightforward. The previous way of initializing the SDK is via the setServiceAccount() method:
FileInputStream serviceAccount = new FileInputStream("path/to/serviceAccountCredentials.json");

FirebaseOptions options = new FirebaseOptions.Builder()
.setServiceAccount(serviceAccount)
.setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com")
.build();

FirebaseApp.initializeApp(options);
The updated way of initializing the SDK is via the setCredential() method.
FileInputStream serviceAccount = new FileInputStream("path/to/serviceAccountCredentials.json");

FirebaseOptions options = new FirebaseOptions.Builder()
.setCredential(FirebaseCredentials.fromCertificate(serviceAccount))
.setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com")
.build();

FirebaseApp.initializeApp(options);
The Admin Java SDK now includes a credential implementation based on Google Application Default Credentials. This allows for auto-discovery of service account credentials on Google infrastructure like Google App Engine and Google Compute Engine. This means you don't need to manage service account credentials yourself. Instead, you can make use of Google Application Default Credentials to run the same exact code on your local, staging, and production environments, no configuration required.
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredential(FirebaseCredentials.applicationDefault())
.setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com")
.build();

FirebaseApp.initializeApp(options);
See Initialize the SDK for more code samples and detailed documentation.
What's next for the Admin SDKs?
We are continually striving to expand our first-class support for backend developers in the Firebase ecosystem. Stay tuned for more features to be added to the Firebase Admin SDKs in the future! If you'd like to see a specific feature, let us know by sending us a note through our feature request support channel.
Share:

Tuesday, 31 January 2017

Debugging Firebase Cloud Messaging on iOS

Todd Kerpleman
Todd Kerpelman
Developer Advocate
Debugging Firebase Cloud Messaging is one of the most common Firebase-on-iOS questions I see on StackOverflow. And so in an effort to garner as many StackOverflow points as I can (oh, yeah, and to educate the developer community), I thought it might be helpful to write up a full debugging guide on what to do when you can't seem to get Firebase Cloud Messaging (FCM) working on your iOS device. First off, I'd recommend taking a moment to watch our Understanding FCM on iOS video. It'll give you a better idea of what's going on underneath the hood, which is always useful when you're trying to debug things. Go ahead! I'll wait.



Okay, back? So you probably noticed in the video that we have several systems all talking to each other:
  1. Your app server (or Firebase Notifications) talks to Firebase Cloud Messaging
  2. Firebase Cloud Messaging then talks to APNs
  3. APNs talks to your user's target device
  4. On your user's target device, iOS communicates with your app.


These four paths of communication means there are four opportunities for things to go wrong. And when they do, they very often manifest as a frustrating "It says my notification was sent, but nothing showed up on my device" kind of bug, which requires some real detective work. So here are the steps I recommend you go through to start tracking down these errors.

1. Temporarily disable any connectToFCM() calls

If you'll recall from the video, your app can explicitly connect to Firebase Cloud Messaging by calling connectToFCM()when it's in the foreground, which allows it to receive data-only messages that don't have a content-available flag directly through FCM.
And while this can be useful in certain circumstances, I recommend disabling this while you're debugging. Simply because it's one extra factor that you want to eliminate. I've seen a few, "My app receives notifications in the foreground, but not in the background" problems out there that probably occurred because the developer was only receiving messages through the FCM channel, and their APNs setup was never actually working properly .
If things break at this point: If you suddenly go from "Hey, I was receiving foreground notifications" to "I'm not receiving any notifications at all", then this is a sign your app was never properly set up to receive notifications from APNs in the first place. So your app might be a little more broken than before, but at least now it's consistently broken. (Hooray!) Keep reading to debug your APNs implementation!
For the next several steps, we're going to go backwards through that "Notifications to FCM to APNs to iOS to your app" chain. Let's start by making sure that iOS can actually speak to your app...

2. Add some good ol' fashioned print() debugging

Thanks to some clever method swizzling, Firebase Cloud Messaging makes it totally unnecessary for you to implement either application(_:didRegisterForRemoteNotificationsWithDeviceToken:) or application(_:didFailToRegisterForRemoteNotificationsWithError:) in your app delegate.
However, for debugging purposes, I like to add in these methods and print out some debug information to see if there are any errors happening that I should be aware of. Start by adding some debug output to your failure method. Something like this:
func application(_ application: UIApplication,
didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Oh no! Failed to register for remote notifications with error \(error)")
}
In theory, any error message printed out here will also probably be printed out by the FCM client library, but I like having my own messages because I can search for specific strings (like "Oh no!" in the above example) among all the Xcode output. This also gives me a handy line of code where I can add a breakpoint.
While you're at it, in your didRegister... method, go ahead and print out a human-readable version of your device token:
func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
var readableToken: String = ""
for i in 0..<deviceToken.count {
readableToken += String(format: "%02.2hhx", deviceToken[i] as CVarArg)
}
print("Received an APNs device token: \(readableToken)")
}
You don't need to disable method swizzling or anything to add these debug methods. Firebase will go ahead and call them just as soon as it's done calling its own set of methods.
If you're seeing an error message at this point: If you either receive an error message or don't get back a device token, check the error message for a good hint as to what went wrong. Most mistakes at this point fall under the, "I'm embarrassed to tell anybody why it wasn't working" category. Things like:
  • Testing on the iOS simulator and not the device.
  • Forgetting to enable Push Notifications in your Xcode project settings.
  • Not calling application.registerForRemoteNotifications() when your app starts up.
Sure, these are simple mistakes, but without the benefit of printing out messages to the Xcode console, it's easy for them to go unnoticed.

3. Confirm that you can send user-visible notifications

As with any iOS app, you need to explicitly get the user's permission to show any kind of notification alert or sound. If you're in a situation where your app doesn't appear to be receiving notification messages in the background, your app simply might not have permission from iOS to do so.
You can check this in iOS >= 10 by adding the following code somewhere in your app.
UNUserNotificationCenter.current().getNotificationSettings { (settings) in
print("Alert setting is \(settings.alertSetting ==
UNNotificationSetting.enabled ? "enabled" : "disabled")")
print("Sound setting is \(settings.soundSetting ==
UNNotificationSetting.enabled ? "enabled" : "disabled")")
}
If you're seeing "disabled" messages at this point: Either you accidentally denied granting your app permission to send you notifications, or you never asked for permission in the first place.
If you accidentally clicked on the "Don't allow" button when the app asked you for permission to send notifications, you can fix this by going to Settings, finding your app, clicking on Notifications, then clicking the Allow Notifications switch.

                                   

On the other hand, if you never asked for permission to show user-visible permissions, then it means you need to add code like this (for iOS >= 10) within your app somewhere:
let authOptions : UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(options: authOptions)
{ (granted, error) in
if (error != nil) {
print("I received the following error: \(error)")
} else if (granted) {
print ("Authorization was granted!")
} else {
print ("Authorization was not granted. :(")
}
}
But if everything looks good at this point, you can move on to debugging the APNs connection!

4. Make a call directly through APNs

Remember; just because you're using FCM to handle your notifications doesn't mean you can't also use APNs directly. There are a few ways you can try this; one option is to use an open-source tool like NWPusher to send test notifications. But personally, I prefer sending APNs requests directly through a curl call.
Making an APNs curl request is easier these days now that APNs supports HTTP/2. But it does mean you'll need to make sure your copy of curl is up-to-date. To find out, run curl --version. You'll probably see something like this:
curl 7.47.1 (x86_64-apple-darwin15.6.0) libcurl/7.47.1 OpenSSL/1.0.2f zlib/1.2.5 nghttp2/1.8.0
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets
If you want to talk to APNs, you'll need a version of curl that's greater than 7.43, and you'll need to see HTTP2 among the features. If your version of curl doesn't meet these requirements, you'll need to update it. This blog post by Simone Carletti gives you some pretty nice instructions on how to do that.
Next, you'll need to convert the .p12 file you downloaded from the Apple Developer Portal to a .pem file. You can do that with this command:
openssl pkcs12 -in MyApp_APNS_Certificate.p12 -out myapp-push-cert.pem -nodes -clcerts
You'll also need the APNs device token for your target device. If you added the debug text listed earlier in your application(_:didRegisterForRemoteNotificationsWithDeviceToken:) method, you'll be able to grab this from your Xcode console. It should look something like ab8293ad24537c838539ba23457183bfed334193518edf258385266422013ac0d
Now you can make a curl call that looks something like this:
> curl --http2 --cert ./myapp-push-cert.pem \
-H "apns-topic: com.example.yourapp.bundleID" \
-d '{"aps":{"alert":"Hello from APNs!","sound":"default"}}' \
https://api.development.push.apple.com/3/device/ab8293ad24537c838539ba23457183bfed334193518edf258385266422013ac0d
Three things to notice here:
  1. That --cert argument should link to the .pem file you created in the previous step.
  2. For the apns-topic, include the bundle ID of your app. And yes, the concept of apns-topics are completely different than Firebase Cloud Messaging topics.
  3. Make sure your device ID is included at the end of that URL there. Don't just copy-and-paste the one that I have. It won't work.
If all has gone well, you'll see a push notification on the device, and you can move on to the next step. If not, here's a few things to look for:
  1. Are you getting back any error message from APNs? That's a pretty good sign something has gone wrong. Common messages include:
    1. "Bad device token" -- This is what it sounds like. Your device token is incorrect. Double-check that you've copied it correctly from your app
    2. "Device token not for topic" -- This might mean that your topic isn't properly set to your app's bundle ID. But it also might mean that you're not using the correct certificate here -- I've gotten this message when I've used the wrong .pem file.
  2. Is your app in the background? Remember that iOS will not automatically show notification alerts or sounds if your app is in the foreground.
    1. However, in iOS 10, they've made it significantly easier to have iOS show these alerts even if your app is in the foreground. You just need to call completionHandler([.alert]) at the end of userNotificationCenter(_:willPresent:withCompletionHandler:)
  3. Are you sending valid APNs requests? There are a few types of requests that, while syntactically correct, may still get rejected. At the time of this writing, these include sending silent notifications that don't include the content-available flag, or sending silent notifications high priority.
    1. In addition, iOS may throttle silent notifications if your app neglects to call its completionHandler in a reasonable amount of time upon receiving them or uses too much power to process these notifications. Refer to Apple's documentation for more information.
  4. Is APNs having issues? You can double-check the status of APNs and the APNs Sandbox over at https://developer.apple.com/system-status/
But if things seem to be working correctly here, it's time to move on to the next step...

5. Make a curl call directly through FCM

Once you've confirmed your APNs call seems to be working properly, the next step is to confirm the FCM part of the process is working. For that, I also like to make another curl call. For this to work, you're going to need two things: The server key and the FCM device token of your target device.
To get the server key, you'll need to go to the Cloud Messaging settings of your project in the Firebase Console. Your server key should be listed there as a giant 175-character string.



Getting your FCM device token is slightly more work. When your app first receives an APNs token, it will send that off to the FCM servers in exchange for an FCM device token. When it gets this FCM token back, the FCM library will trigger an "Instance ID Token Refresh" notification. 1
So listening to this firInstanceIDTokenRefresh NSNotification will let you know what your FCM device token is, but this notification only gets triggered when your device token changes. This happens infrequently -- like when you switch from a debug to production build, or when you run your app for the first time. Otherwise, this notification will not be called.
However, you can retrieve your cached FCM device token simply through the InstanceID library, which will give you any stored device token if it's available. So to get your latest-and-greatest FCM token, you'll want to write some code like this:
  func application(_ application: UIApplication, didFinishLaunchingWithOptions
// ...
printFCMToken() // This will be nil the first time, but it will give you a value on most subsequent runs
NotificationCenter.default.addObserver(self,
selector: #selector(tokenRefreshNotification),
name: NSNotification.Name.firInstanceIDTokenRefresh,
object: nil)
application.registerForRemoteNotifications()
//...
}

func printFCMToken() {
if let token = FIRInstanceID.instanceID().token() {
print("Your FCM token is \(token)")
} else {
print("You don't yet have an FCM token.")
}
}

func tokenRefreshNotification(_ notification: NSNotification?) {
if let updatedToken = FIRInstanceID.instanceID().token() {
printFCMToken()
// Do other work here like sending the FCM token to your server
} else {
print("We don't have an FCM token yet")
}
}
The very first time your app runs, you'll see a message that you don't have an FCM token, followed by a message a short time later with your actual token. In subsequent runs, you should see your cached token right away. It's a 153-character random string that looks a lot like your server key, so don't get 'em confused.
So, now that you have both pieces of information, you can make a curl call. Try calling something like this:
> curl --header "Content-Type: application/json" \
--header "Authorization: key=AU...the rest of your server key...s38txvmxME-W1N4" \
https://fcm.googleapis.com/fcm/send \
-d '{"notification": {"body": "Hello from curl via FCM!", "sound": "default"},
"priority": "high",
"to": "gJHcrfzW2Y:APA91...the rest of your FCM token...-JgS70Jm"}'
If all has gone well, you'll see a notification on your device, as well as receive a "Success" response from FCM.
{"multicast_id":86655058283942579,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1486683492595106961%9e7ad9838bdea651f9"}]}
Don't get too excited by this success response. That just means FCM has successfully received your message; it doesn't mean that it has successfully delivered it to APNs. You really want to look for the notification on your device.
If your notification doesn't seem to be getting received, here's a few things to look out for:
  • Are you seeing an error message in your response? Don't ignore those. They're usually pretty big hints as to what's going on.
    • InvalidRegistration means you don't have the correct FCM device token. (Remember, it's actually called a "registration token")
    • A 401 error with the message "The request's Authentification (Server-) Key contained an invalid or malformed FCM-Token" means the server key is probably incorrect. Make sure you've copied the whole thing correctly from the Firebase console.
  • Is your priority set to high? Android and iOS devices have different interpretations of medium and high priority values.
  • On Android, medium priority basically means, "Send the message, but be respectful of your user's device if it's in doze mode". This is generally why FCM uses "medium" as its default priority if you don't specify one.
    • On iOS, medium (or 5) priority can best be summarized as, "Maybe we'll send it at some point. But in this crazy world of ours, who can say for sure?!? ¯\_(ツ)_/¯".
    • This is why APNs defaults to a priority value of 10 (or "high") when no priority value is specified and they really only ask you to send messages medium priority when you're sending a data-only content-available message.
    • Ideally, you should send most user-visible messages with medium priority to Android devices and high priority to iOS devices. If you're using the Firebase Notifications panel, you can do this pretty easily.
  • Are you using APNs syntax instead of FCM syntax? While FCM will properly translate FCM-speak to APNs, it will get confused if you send it APNs syntax in the first place. So double-check that you're sending messages properly formatted for FCM. In particular, confirm that you're setting "priority" to "high" and not "10".
    • If you're sending a content available message, make sure you're specifying "content_available": true with an underscore and not "content-available": 2
    • I also recommend trying to send a Notification through the Firebase Notifications panel at this point. If you can make a call through Notifications but not through a curl call, it might be a sign that your message isn't properly formatted.
  • Have you uploaded your APNs certificate to the Firebase console? And has it expired? Remember, FCM needs that certificate in order to communicate with APNs.

6. Make a call through the Notifications panel and/or your server

So if you've gotten to this point, we've basically established that the path from FCM to APNs to iOS to your app is working correctly. So I would be very surprised if the Notifications panel wasn't working at this point. If it is, the best thing to do is check status.firebase.google.com and see if there are any issues with the Cloud Messaging service. (This also includes the Notifications panel)
If the problem is with your server code, well… that's up to you and your server. But now that you've figured out exactly what data you need to generate to make a proper FCM call, I'm hoping you can tackle this part on your own with confidence. Or, at least, the appearance of confidence, which is enough to fool most people.

Whew! Well, I know that was a lot to go through, and hopefully you were able to stop at, like, step 2 because it turns out you forgot to flip some switch in your Xcode project. If that's the case, you're probably not even reading this conclusion. Come to think of it, if you made it this far, it's probably because you're still having problems with your implementation, in which case… uh… go check out our support channels. Or ask @lmoroney, because I'm basically out of suggestions at this point.

Thanks for reading!

[1] That's an NSNotification, not an APNs notification. Hooray for overloaded terms!
[2] One interesting error I ran into was a developer who couldn't understand why his content-available messages were only being received when his app was in the foreground. It turns out he had explicitly connected to FCM (like in step 1) and was using the (invalid) "content-available" key in his message. Since FCM didn't translate this into a valid APNs content-available message, it interpreted it as a data-only message that should only be sent over FCM, which is why it only worked when his app was in the foreground.
Share:

Monday, 14 November 2016

Announcing Firebase for Unity

Todd Kerpleman
Todd Kerpelman
Developer Advocate

Did you know that Firebase contains a whole bunch of features that makes it easier for you as a developer to build awesome apps?

Yeah, okay. That's probably not news.

But you might have noticed that, for a while, we've been talking about "apps" instead of "games". And that's because our mobile libraries work great... as long as you're writing your apps in Swift, Java, or Objective-C.

The problem is that most game developers are either building their own game engines in C++ or using popular 3rd party game platforms like Cocos2D or Unity to power their mobile games. And while we've had a C++ version of the Firebase library available in beta for a while now, our Unity developers have been left with a rather out-of-date Firebase Database plugin...

...until now! Thanks to a lot of hard work from a lot of our engineers and your continued feedback, there's a brand new, officially supported, Unity SDK that includes a whole lot more of the Firebase platform.

So what does this offering mean for you as a Unity developer? It means you can now take advantage of many of the new Firebase features that we announced back in May. Including...

Firebase Analytics: A free and unlimited analytics package to record events that happen within your game. Find out where in your game players are getting stuck, how your audience is growing over time, or where players from each different country are spending their premium currency. All of this is easy to record with Firebase Analytics, and its integration with BigQuery allows you to run some pretty sophisticated data mining along the way.

The Firebase Real-time Database: This is a database where your app's data magically syncs across all devices, usually within a few hundred milliseconds. It's great for near-real-time features like in-game chat, syncing your user's saved game across devices, or potentially powering a turn-based board, card, or strategy game. That said, you probably don't want to use it to drive your multiplayer shooter or MOBA -- I know with game developers, we need to a little more explicit about what 'real-time' actually means. ;)

Dynamic Links. These are mobile deep links that you can use to point players to any element of your game (if they have it installed), or take them to the Play Store / App Store (if they don't). I think the best use case here for game developers would be to use Dynamic Links to help power in-app sharing. You can use Dynamic Links to share a replay of a level, or a link to your player's awesome new character / fortress / user-generated content. And if you don't feel like building our your own interface to do all of this, Firebase Invites can create one for you, by packaging up a Dynamic Link inside a nicely formatted email or SMS message.

Authentication: "Boy, I really like spending all my time building authentication systems instead of working on my game," said no game developer ever. With Firebase Auth, we make it easier for you to sign in your users in from third party providers like Facebook, Google, and Github, or to create a custom username and password system.

Cloud Messaging: Firebase Cloud Messaging allows you to send notifications to both iOS and Android devices through a single endpoint. It also lets you send notifications through the Firebase Notifications panel, which means non-technical members of your team can send notifications without your having to worry about writing any custom server code or curl calls.

Remote Config: This feature lets you update your game's values from the cloud. Honestly, this is the feature I'm most excited about for games. Anybody who's designed a tower defense game knows that one overpowered stat in a single unit can throw off the balance of your entire game. With Remote Config you can tweak those values from the cloud, and then use Firebase Analytics to see if they give you the results you expect. You can even use Remote Config to deliver custom values to specific groups of people, like your expert players.

You can use this library with Android and iOS devices, but the team has nicely added in stub methods for Windows, OSX, and Linux, so you don't need to worry about adding a bunch of conditional code if your game is also targeting desktops. As a side note, the Real-time Database part of the SDK works directly within the Unity editor, which makes testing and debugging a bit nicer.

We encourage you to give the Firebase SDK for Unity a try! It's available right here, and it contains a whole bunch of features that makes it easier for you as a developer to build some pretty awesome… games.

Yeah, that felt good to write.

Share:

Monday, 17 October 2016

Announcing Firebase Cloud Messaging for Web

Pinar Ozlen
Software Engineer

Today we're announcing web support for Firebase Cloud Messaging (FCM) with the release of a JavaScript library. This extends our current browser support, enables a dramatically simpler implementation process, and brings powerful features such as Topics and Device Group Messaging to the web.

Notifications are one of the most compelling tools for developers to build engaging experiences. Since we introduced the technology in Chrome, we've seen tremendous adoption, with more than 10B notifications being sent per day to websites. However, developers often tell us that implementing this feature on the Web can be challenging and that they want to access the same advanced features of FCM that are available on native notifications.

Firebase Cloud Messaging is a powerful system that already supports sending messages to iOS apps, Android apps, and Chrome. Starting today, developers can use FCM to send messages to browsers that support the Push API, allowing you to go beyond Chrome and also send to Firefox, Opera and others.

It is easier than ever to send notifications to your web users with the FCM JavaScript library, as FCM handles complex server-side features such as payload encryption and client-side features such as service workers.

You can use a default service worker implementation to get started quickly, and when you are ready to extend and override it, you can do so easily. In addition to this, when you’re using the FCM APIs, our servers can manage payload encryption for you. FCM users don't need to change a thing in their server implementation to achieve this!

However, the technical aspect of web notifications is just a start. In order to make the most out of web notifications, you need to engage your users with the right content in the right manner. Check out our “What Makes a Good Notification?” post for best practices on notification content and “Best Practices for Push Notifications Permissions UX“ post for tips on interacting with Web users to get permission for sending notifications.

Which FCM features are supported?

Beyond providing an easier client implementation, the FCM JavaScript library also brings important FCM features to the Web.

With the FCM JavaScript library, you can send web push notifications to single devices, topics or groups of devices. With the addition of topic support on the Web, we are making it possible for developers to send a message to their Android, iOS and Web users who have opted in to a particular topic. To take advantage of topics and device groups, you can use the server-side APIs to manage your topics and groups subscriptions.

Browser Coverage

Currently the FCM JavaScript library enables developers to reach browsers that have Push API support. Namely:

  • Chrome Desktop and Mobile (version 50+)
  • Firefox Desktop and Mobile (version 44+)
  • Opera on Mobile (version 37+)

Microsoft Edge has announced plans to support the Push API and Samsung Browser will be covered once they have message payload support. This coverage will increase over time as more browsers introduce support for service workers. Make sure to check out our release notes for updates!

How do I Get Started?

Just follow our Getting Started guide, and make sure to checkout our Firecast video!

What have our partners done?

We have been working with early adopters to test, refine, and unleash the power of the new FCM JavaScript library, and create the best possible Web notification experience for users. Below are some of their success stories:

“We were unable to find any effective solution for notifications until we found FCM… FCM is the best solution because of its rich features, stable performance, and easy deployment.”
Zou Yu, Director of Alibaba.com Mobile

Alibaba.com, the leading wholesale marketplace connecting overseas buyers with suppliers in China, implemented our solution in two days and saw 4X higher engagement for users who receive web notifications compared with users who visit the website directly. See the full Alibaba.com case study.

“Firebase Cloud Messaging meets our requirements perfectly.”
Lijun Chen, Director, AliExpress

AliExpress, a global retail marketplace, saw a 93.4% higher open rate on the web compared to their app notifications, and a 178% higher conversion compared to mobile site users who do not receive notifications. The AliExpress team is continuing to expand their uses cases. For instance, to promote sales on 11th November (also referred to as “Double 11”) - a festival commonly celebrated by young Chinese singles and also one of the biggest online shopping events in the world - AliExpress will be using FCM to send notifications on its website to remind users to take advantage of discounts on items they are interested in. See the full AliExpress case study.

“The initial implementation was very easy - really a one-day job.”
Filip Procházka, Developer

Settle Up, a fast-growing startup that helps users track shared expenses, wanted to send notifications to users when changes were made to a bill. After implementing in a day, they began to see 37% higher engagement for users who receive web notifications. Moreover, as a user of Firebase Analytics, Crash Reporting, Hosting, and Test Lab, Settle Up was able to easily access all their tools through Firebase as a unified solution. See the full Settle Up case study.

Start now

Firebase Cloud Messaging is part of the Firebase platform and is available for free. We are excited to announce this launch and can’t wait to hear what you think!

Share:

Wednesday, 10 August 2016

Sending notifications between Android devices with Firebase Database and Cloud Messaging


Frank van Puffelen
Frank van Puffelen
Engineer

In this article we will show how to send notifications between Android devices using Firebase Database, Cloud Messaging and Node.js. Since this article was written, we also released Cloud Functions for Firebase, which offers a way to send notifications without requiring a Node.js server. See the documentation on sending notifications with Cloud Functions to learn more.
The Firebase Database is a great back-end for building multi-user mobile applications. Whenever multiple users have the application open, changes that any user makes are synchronized to all other connected users within milliseconds.
A great example of this is a chat application: any message that a user sends is instantly synchronized to other users. That leads to a very smooth chat experience.
But what if one of the users doesn't have the application running on their Android device? That means that the device is not connected to the Firebase Database servers, so it will not receive the changes automatically. This is fine for regular chat messages, but in most chat apps you want to pull the user back in when someone @ mentions them (e.g. "hey @puf, can you help out here?")
For this scenario, you'll typically send a notification to the user's device using Firebase Cloud Messaging. Such a notification will then show up in the notification area of the device, providing a great way to get the user back into the application when an interesting event happens.
In this article, we'll use Firebase Cloud Messaging to deliver the notification to the device. We'll write a Node script that interacts with FCM, so that we don't have to expose our API key on the Android devices. But first: we need to figure out what the code for sending a notification will look like on the Android device itself.

Sending a push notification from the Android app

To send a notification to a user, our Android application does the following:
sendNotificationToUser("puf", "Hi there puf!");
The sendNotificationToUser() method is a helper that we implemented like this:
public static void sendNotificationToUser(String user, final String message) {
Firebase ref = new Firebase(FIREBASE_URL);
final Firebase notifications = ref.child("notificationRequests");

Map notification = new HashMap<>();
notification.put("username", user);
notification.put("message", message);

notifications.push().setValue(notification);
}
This is probably not what you expected. This code just writes the notification data to the Database. How is that sending a notification?
It is not. We are using the database as a queue here. Our Android app writes the request to send a notification into the database, where our Node script will pick it up and send the notification through Cloud Messaging. We'll have a look at that script in a minute. First, we want to talk a bit about how we structured the data for this application.

Data structure

Just like with any application, the data structure is probably one of the most important parts of your Firebase-backed application. We've already seen the data structure for sending notifications:
  notificationRequests
$pushid
message: "Hello there"
username: "puf"
This is the node that our Android application was writing to. Each notification request consists of the message that we're sending and the name of the user we're notifying. How we're mapping the username to an actual notification depends a bit on your application. But in this case, we're going to use topic based notification: a username is mapped to a topic /topics/user_. So in my case the message will be sent to (and the Android application will subscribe to) /topics/user_puf.
Now it's about time we get to the Node code I've been talking about.

Node code

Now that we know how the Android app writes a notification request into the database, and we know what the database structure looks like, it's time to write the code that will actually be sending the notifications.
This is going to be a Node process, which runs on a trusted environment, such as a Google App Engine Flexible Environment. The node script monitors the notification queue that we saw above. For every child that is added to this queue, it extracts the necessary information and then calls the Cloud Messaging REST API to send the notification. If that succeeds, it removes the notification request from the queue.
var firebase = require('firebase-admin');
var request = require('request');

var API_KEY = "..."; // Your Firebase Cloud Messaging Server API key

// Fetch the service account key JSON file contents
var serviceAccount = require("path/to/serviceAccountKey.json");

// Initialize the app with a service account, granting admin privileges
firebase.initializeApp({
credential: firebase.credential.cert(serviceAccount),
databaseURL: "https://<your database>.firebaseio.com/"
});
ref = firebase.database().ref();

function listenForNotificationRequests() {
var requests = ref.child('notificationRequests');
requests.on('child_added', function(requestSnapshot) {
var request = requestSnapshot.val();
sendNotificationToUser(
request.username,
request.message,
function() {
requestSnapshot.ref.remove();
}
);
}, function(error) {
console.error(error);
});
};

function sendNotificationToUser(username, message, onSuccess) {
request({
url: 'https://fcm.googleapis.com/fcm/send',
method: 'POST',
headers: {
'Content-Type' :' application/json',
'Authorization': 'key='+API_KEY
},
body: JSON.stringify({
notification: {
title: message
},
to : '/topics/user_'+username
})
}, function(error, response, body) {
if (error) { console.error(error); }
else if (response.statusCode >= 400) {
console.error('HTTP Error: '+response.statusCode+' - '+response.statusMessage);
}
else {
onSuccess();
}
});
}

// start listening
listenForNotificationRequests();
For more information on accessing Firebase from a server, see how to set up the Firebase Admin SDK. If you're new to running your own node.js script on a server, learn more about running node.js on Google Cloud Platform. To learn how to send notifications without requiring a Node.js server, see the documentation on sending notifications with Cloud Functions.
Since we're listening for child_added events, we'll end up calling sendNotificationToUser() for each notification request in the queue. If sending succeeds, we remove the request from the queue. There is no auto-retry in this simple script, so it will only retry failed notifications when you restart the script. For a more scalable approach, consider using our firebase-queue library.
You've probably also noticed that we have an API_KEY constant in the script. That is the key that we got from Firebase Cloud Messaging to be able to send message. It is also the exact reason why we don't want to run this code in the Android application itself: knowing the API key opens you up to abuse, since it can be used to send messages on your behalf. By having this key in our Node script on a server, we make sure the users of our Android application can't get at it.

Receiving a notification in the Android app

The code for Android is pretty minimal, thanks to the way the Firebase Cloud Messaging SDK handles notification messages. When it receives a notification message while the app is in the background, it displays a message in the system notification area. When the user clicks the message, it automatically opens the app. This type of re-engagement is exactly what we want for this app, so we really only have to include the Firebase Messaging library and subscribe to the topic of our user name.

Subscribe to the topic

We are using a topic that matches our user name to ensure we get messages that are meant for this user.
String username = "puf";
FirebaseMessaging.getInstance().subscribeToTopic("user_"+username);
We've hard-coded the username in this snippet, since it depends on your app. But you can see that once you've determined the user name, all it takes to register for notifications (and display them when the app is backgrounded) is a single line of code.
If you'd also like to handle the notification when your app is in the foreground or would like to send more data along with the message, read the documentation about Firebase Cloud Messaging and its message types.

Summary

This post shows how you can send push notifications to an Android application using Firebase and a Node script. We've sent the notification from Android code, but could just as easily send them from any other application that can access the Firebase Database. Adding iOS support is easy too: just add the dependency and register for remote notifications.
Share:

Tuesday, 14 June 2016

Introducing Firebase Notifications

Laurence Moroney
Laurence Moroney
Developer Advocate

Firebase Notifications is a free service that enables user notifications for Android and iOS devices. Through the Firebase console, you can send notifications quickly and easily across platforms with no server coding required. These notifications can be directed at your individual users; to topics that they subscribe to; or to segments defined by analytics audiences.

Notifications is built on Firebase Cloud Messaging, and provides an option that lets you create a notification platform with minimal coding effort. It supports a graphical console for sending messages, removing the need for you to create a server. With this console, you can re-engage and retain your user base, foster app growth, and support marketing campaigns. If you are currently using Google Cloud Messaging, we highly encourage you to migrate to Firebase Cloud Messaging to for your Android and iOS apps to take advantage of Firebase Notifications. Check out our migration guide here.

Firebase Notifications integrates closely with Firebase Analytics, allowing you to define custom audiences and direct notifications to them. So, for example, you can send notifications to user segments for a particular app, version of an app, or language.

Creating notifications is very straightforward -- you simply use the Firebase Notifications GUI in the console to compose and send notifications to apps that are linked to your project in the console. When your app is in the background on a user’s device, notifications are delivered to the system tray. Tapping the notification opens the app. With a little code, it’s easy to add handlers to receive the message when the app is in the foreground, and respond to it by, for example, launching a foreground activity.

This talk about Firebase Notifications from Google I/O 2016, goes over Firebase Notifications, showing how the console works, as well as how easy it is to write code to implement notifications into your app or site.

Busbud uses Firebase Notifications to easily engage with customers traveling around the world

Busbud is the bus travel booking website, serving over ten million departures to travelers around the world every week. It lets the user search, compare and buy tickets from hundreds of bus companies in thousands of cities and bus routes. It uses notifications to communicate with users about changes that are relevant to them, and to re-engage with them with discount codes and promotions.

Using Firebase Notifications, they were able to send, receive and see push notifications in 3 minutes. They only needed to re-compile their app using the Firebase libraries. Once done, they were able to send messages to users in a specific language, audience or topic using a single line of code.

“Firebase [Notifications] let Busbud jettison code we didn't want to maintain, made it trivial to send new targeted notifications via the console while tracking engagement and is a powerful tool that makes the Busbud app a great companion for bus travellers.” Jean Baptiste Morin, Lead Mobile Developer, Busbud

You can learn more about Firebase Notifications at the Google Developers site, where you can see documentation and examples for Firebase Notifications on Android and iOS.

Share:

Tuesday, 31 May 2016

Introducing Firebase Cloud Messaging

Laurence Moroney
Laurence Moroney
Developer Advocate

Firebase Cloud Messaging is a cross-platform messaging solution that lets you reliably deliver messages and notifications to Android, iOS or the Web at no cost. For example, you can specify that new data is available for sync, special offers are ready to re-engage users and more. Messages can be sent to individual devices, groups of devices, or even topics that devices are subscribed to.

Messages can carry a payload of up to 4k, and can also be sent upstream from devices to a central server or other devices.

Firebase Cloud Messaging is the successor to Google Cloud Messaging, and you can learn details here about your options if you already use Google Cloud Messaging.

We’ve provided some great samples if you want to get started in building apps that use Firebase Cloud Messaging, or you can follow the walkthroughs on Android, iOS or the Web.

Share: