How to get better insight into push notification delivery

Header image from blog post titled how to get better insight into push notification delivery
Header image from blog post titled how to get better insight into push notification delivery

This article is part of the weekly learning pathways we’re releasing leading up to Firebase Summit. See the full pathway and register for the summit here.

When you send a push notification to your users, things can go wrong in many places: the network might be down, the device might have performance issues or the send request might be invalid. And each platform has its own complexity so the challenges can keep adding up. All of this makes it difficult to know whether your notifications actually got delivered to users.

To get a better understanding of whether your notifications were delivered and where things might have gone wrong, you need one central place to collect all information and then run an analysis. This is where BigQuery can help. BigQuery, Google’s solution for building data warehouses, gives you the ability to run queries and build custom dashboards that provide deep insights and actionable information.

With the Firebase Cloud Messaging Android SDK, you can log notification delivery data and export it to BigQuery. We recently expanded the same support for iOS and the web. In this article, we will walk you through the process of setting this up so you can better understand your delivery rate and identify ways to troubleshoot or improve it.

Troubleshooting delivery rate

Enable BigQuery Export for your Firebase project

First, you need to enable BigQuery for your Firebase project. You can do this by navigating to the Firebase console > Project Settings > Integrations, and then click Link on the BigQuery card. It’s worth noting that, by default, this integration uses the BigQuery sandbox. This lets you explore BigQuery capabilities at no cost, so you can evaluate if it fits your use case. After you link your Firebase project to BigQuery, Firebase will export your data to BigQuery. The initial propagation of data might take up to 48 hours to complete.

You can do this by navigating to the Firebase console > Project Settings > Integrations, and then click Link on the BigQuery card
You can do this by navigating to the Firebase console > Project Settings > Integrations, and then click Link on the BigQuery card

Once the data is successfully exported, you should be able to see a data table created under your project’s firebase_messaging tab in the BigQuery console.

To collect Notification Delivery data, you need to enable logging on the client side. In the next step, we’re going to set up the iOS client and start logging some data to BigQuery.

iOS Delivery Data Logging

With the Firebase Messaging iOS SDK 8.6.0 or higher, you can now enable notification delivery logging in your app that exports to BigQuery by calling a new API we recently added. You will need to log alert and background notifications separately (this is only required for Apple’s platforms).

Alert notifications and Notification Service Extension

To log alert notifications delivery, you first need to add a Notification Service Extension to your project in Xcode. The Notification Service Extension lets you customize the content of notifications before they become visible to users. Apple’s developer documentation has more details about how to add a service extension to your project.

To log alert notifications delivery, you first need to add a Notification Service Extension to your project in Xcode
To log alert notifications delivery, you first need to add a Notification Service Extension to your project in Xcode

After adding the Notification Service Extension to your project, find the NotificationService didReceiveNotificationRequest:withContentHandler: method inside the service extension target. This is where you will add code to enable logging.

In Firebase 8.6.0, We have introduced a new method to the Firebase Messaging API: the delivery data export API FIRMessagingExtensionHelper exportDeliveryMetricsToBigQueryWithMessageInfo:. Logging is disabled by default, so you will need to explicitly enable it by calling this API inside the Notification Service Extension.

 override func didReceive(_ request: UNNotificationRequest,
                           withContentHandler contentHandler: @escaping (UNNotificationContent)
                             -> Void) {
    self.contentHandler = contentHandler
    bestAttemptContent = (request.content.mutableCopy() 
                          as? UNMutableNotificationContent)

    if let bestAttemptContent = bestAttemptContent {
      // Modify the notification content here...
      bestAttemptContent.title = "(bestAttemptContent.title) 👩🏻‍💻"

      // Log Delivery signals and export to BigQuery.
      Messaging.serviceExtension()
        .exportDeliveryMetricsToBigQuery(withMessageInfo: request.content.userInfo)

      // Add image, call this last to finish with the content handler.
      Messaging.serviceExtension()
        .populateNotificationContent(bestAttemptContent, withContentHandler: contentHandler)
    }
  }

Note that, if you use the Firebase Cloud Messaging SDK to add an image to your notification, you need to make sure to call the deliver data export API before calling Messaging.serviceExtension().populateNotificationContent(_:withContentHandler), as shown in the code snippet above.

The Apple system only passes the notification to the service extension if the notification payload contains the key ["mutable-content" :1](https://developer.apple.com/documentation/usernotifications/modifying_content_in_newly_delivered_notifications?language=objc), so make sure you specify this key if you use the HTTP v1 API. If you use the Firebase console to send notifications, "mutable-content" :1 will be set automatically.

Background notifications

Background notifications are hidden messages that allow your app to wake up and update data in the background. To enable delivery data export for these kinds of notifications, you will need to implement the [application:didReceiveRemoteNotification:fetchCompletionHandler:](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623013-application?language=objc) method and call exportDeliveryMetricsToBigQueryWithMessageInfo: method as shown below:

// For background notifications, call the API inside the UIApplicationDelegate method:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
  Messaging.extensionHelper().exportDeliveryMetricsToBigQuery(withMessageInfo:userInfo)
}

Make sure to include ["content-available":1](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/generating_a_remote_notification?language=objc) to specify it’s a background notification when you use the HTTP v1 API to send the notification.

Web Delivery Data Logging (Alpha)

Notification Delivery Logging is newly available on the web for Firebase JS SDK versions 9.0.0 and newer. To enable delivery data export, all you need to do is to enable the flag on a service worker as shown below. This is handled similarly to Android.

// userConsent holds the decision of the user to give big query export consent.
const userConsent = ...;
const messaging = getMessagingInSw(app);
experimentalSetDeliveryMetricsExportedToBigQueryEnabled(messaging, userConsent)

Android Delivery Data Logging

Notification Delivery Logging has been supported on Android since Firebase SDKs version 20.1.0 or higher. On Android, you can call the delivery data logging API to enable data export for both display and data messages like this:

FirebaseMessaging.getInstance().setDeliveryMetricsExportToBigQuery(true)

Turning it off again

By default, Notification Delivery Logging is disabled on all three platforms, and will only be activated once you call the API to enable it for the particular platform your app is running on. You can also deactivate the BigQuery export any time by unlinking your project in the Firebase console.

Results on BigQuery

Once you have successfully logged some data you will see this data in the BigQuery console. Keep in mind that the data is regularly pushed from Firebase to BigQuery and the daily propagation might take some time (up to a couple of hours, depending on the amount of data) to complete.

BigQuery data also includes customized analytics labels that help you to create custom queries. Here’s a preview what type of data you can get from the iOS platform:

Here’s a preview what type of data you can get from the iOS platform
Here’s a preview what type of data you can get from the iOS platform

With the delivery data on BigQuery, you can now run custom queries or build a customized dashboard based on your needs. It provides detailed information about your campaign, including message identifier, message type, SDK platform and timestamp so you can get a lot of useful information helping you identify if the message was sent as expected. You can also segment the data based on your custom analytics labels. And if you are interested in getting additional aggregate information about message delivery on Android, check out this Medium post to find out how to use FCM Aggregation API for advanced data analysis.

View the full learning pathway

Make the most of Firebase and view the full learning pathway on FCM message delivery for additional codelabs, videos and articles. And don’t forget to register for Firebase Summit and join us on November 10th to learn how Firebase can help you accelerate your app development, release with confidence and scale with ease!