Inbox is an optional feature. If you are interested, please contact us.

The Inbox API allows you to fetch and process notifications that this user has previously received, even if their device was offline. You can then do anything you want with the data, such as making a "notification center", where the user can catch up with previous notifications in a list.

The API gives you access to the entire notification, including its raw payload. It also lets you know if the notification has already been read, and allows you to mark one or all notifications as such. Once received/stored in the inbox, your push notifications will remain for a 3 months period.

This screenshot is an example of what you can achieve with the Inbox API. Please note Batch does not include any UI.

Inbox android example

Picking the Right Fetcher

Installation Mode

This mode will fetch notifications from the current app installation, and nothing else. If the user clears the app's data, this inbox will be cleared. This is great for applications where your users don't have to log in.

In this mode, you can simply get the Inbox Fetcher with no arguments:

var inboxFetcher = await BatchInbox.instance.getFetcherForInstallation();
// inboxFetcher.dispose() - Call this once you're done with it, to free native memory.

Note: This may cause privacy issues if your app has an identification system. Users sharing the same device and using different accounts in your app would be able to see the push history of previous users.

Custom User ID Mode

This mode will fetch notifications for the specified custom user ID, even if they just installed the application and already got notifications on another device logged in with the same user identifier. If your application has a login system, this is the mode you should use.

Since notifications can have sensitive content, you cannot get a user's notifications simply with their user identifier: Batch requires you to authenticate your request.

Getting Your Authentication Key

First, you will need your inbox secret key. You will find that in your dashboard, below your API Keys. It is unique for every app.

Inbox secret dashboard screenshot

The authentication key is generated by computing a sha256 hmac hash of the API Key and the user identifier, using the secret as the key. Then, you have to encode the hash in a hexadecimal string.

For example, in PHP, that would be:

hash_hmac("sha256", $APP_API_KEY . $USER_ID, $INBOX_SECRET)

For the API Key "abcdef", user identifier "paul", and secret of "foobar", the expected authentication key would be 796f1ab5d119d1b2eab8201e60335b56d1befff40c0f80263d64a169a8fd2e45.

Important note: This hash HAS to be computed on your server. If you bundle the inbox secret in your application to compute the hash, attackers will be able to extract it, and read the notifications of any of your users

Getting the Fetcher Instance

Once you've got the authentication key from the server, you only have to give Batch the right user identifier and auth key tuple to get the Inbox Fetcher:

var inboxFetcher = await BatchInbox.instance.getFetcherForUser(userIdentifier: "paul", authenticationKey: "796f1ab5d119d1b2eab8201e60335b56d1befff40c0f80263d64a169a8fd2e45");
// inboxFetcher.dispose() - Call this once you're done with it, to free native memory.

Memory management

As the BatchInboxFetcher instances are backed by native objects, they MUST be released once you're done with them, or the plugin will leak memory due to a Dart limitation.

To do this, call dispose() on the fetcher instance, and clear your reference to it.
Your State's dispose() method is a great place to call BatchInboxFetcher's.

Disposed fetchers are considered dead: calling any method on them will throw an exception.

Fetching Notifications

Now that you've got your fetcher instance, it's time to fetch notifications, and display them!

The inbox fetcher has several important methods and properties:

  • get allNotifications
    This returns a copy of all the notifications that have been fetched. Useful for a list adapter.
    Warning: Calling this always bridges over the native objects, so you should cache that method's result.
  • fetchNewNotifications()
    Allows you to fetch notifications that might have been received after the initial fetch. This is useful for implementing a refresh feature. This will erase the notification history returned by allNotifications to ensure consistency: you should clear the other notification pages you've already from your cache.
  • fetchNextPage() Fetches the next page of notifications. Batch will not fetch all notifications at once, but only small batches of them in pages.
    Use this method to load more notifications.

Note: BatchInboxFetcher and its methods are documented in the API reference.

BatchInboxFetcher will not fetch any notification by default, so before trying to display anything, you will need to call fetchNewNotifications() or fetchNextPage()

Reading Notification Content

Once you've fetched notifications, you will end up with a list of BatchInboxNotificationContent objects.

These objects have everything you need to display these notifications:

  • Title (optional)
  • Body
  • Send timestamp (UTC)
  • Read state
  • Source (Campaign API/Dashboard or Transactional API)
  • Raw payload (as a Map<String, String>). This includes your custom payload.
    • All values are serialized in JSON format to be consistent between iOS and Android. Arrays/Maps will be represented as JSON objects, while numbers and booleans will have to be parsed from the string.

Note: Just like when you get it using standard callbacks, the raw payload should be used carefully on keys you do not control:

  • "aps" is considered private by Apple, and can change at any time. This has happened in the past, where the "alert" object got additional keys for new iOS features.
  • "com.batch" is Batch's internal payload: You should not make any assumption about its content, nor depend on it. We reserve the right to change it at anytime, without warning.
  • Standard parsing good practices apply: Make sure to check every cast and handle errors gracefully, and never assume anything about the payload's content.

Marking Notifications as Read

Notifications can be marked as read in two ways:

  • By marking only one notification as read
    Use markNotificationAsRead() with the notification you want to mark as read.
  • By marking all notifications as read
    Simply call markAllNotificationsAsRead()

In both cases, the notifications will be marked as read locally, but refreshing them might mark them as unread again, as the server might not have processed the request. These methods return quickly, and are thus safe to call on your UI thread.

Note that notifications that have been opened when received are automatically marked as read.

Marking Notifications as Deleted

Notifications can be deleted using the markNotificationAsDeleted() method with the notification you want to mark as deleted. A deleted notification will NOT appear in the notification list the SDK provides, and you will be expected to update your UI accordingly.

The notifications will be marked as deleted locally, but refreshing them might make them appear again, as the server might not have processed the request. These methods return quickly, and are thus safe to call on your UI thread.

Displaying Mobile Landing

1.4 Batch allows you to display a mobile landing attached to a notification. To do so, you can simply trigger the landing message from the BatchInboxFetcher object as following:

void displayLandingMessage(BatchInboxNotificationContent notification) {
    if (notification.hasLandingMessage) {

Tweaking the Fetcher

For more advanced usages, you can also change various aspects of the Inbox Fetcher, such as:

  • The maximum number of notifications fetched per page (maxPageSize property)
  • The maximum number of notifications that can be fetched using this object (limit property)

A default limit is set to avoid going over memory by accident.

This can be configured when getting a fetcher instance:

var inboxFetcher = await BatchInbox.instance.getFetcherForInstallation(maxPageSize: 20, limit: 100);

Testing Your Integration

In order to test your integration, you will need to create a push campaign on the dashboard or to target your installation ID/custom user ID using the Transactional API.

Please note you won't be able to test your implementation using the following methods:

  • Sending a test notification: from the Debug tool or using the "Send a test" button.
  • Targeting a specific push token: in case you are using the Transactional API.
  • Using the Dev API key: Inbox will only work with builds using the Live API key.