Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0062832
BD-7149 Update documentation for upcoming 18.0.0 release.
akrupczynskirezolve Mar 12, 2026
fe1a45c
BD-7149 Update documentation for upcoming 18.0.0 release.
akrupczynskirezolve Mar 13, 2026
280c514
BD-7149 Update documentation for upcoming 18.0.0 release.
akrupczynskirezolve Mar 13, 2026
7e9cd8d
iOS Push Notifications
denniskoluris Mar 16, 2026
840a2cf
Rewritten integration notes
denniskoluris Mar 16, 2026
cfe15d3
Added section to sidebar
denniskoluris Mar 16, 2026
cf9ca16
Minor corrections
denniskoluris Mar 16, 2026
e9b1536
BD-7149 Update documentation for upcoming 18.0.0 release.
akrupczynskirezolve Mar 20, 2026
e23d6c9
BD-7149 Update documentation for upcoming 18.0.0 release.
akrupczynskirezolve Mar 20, 2026
68369d3
BD-7149 Update documentation for upcoming 18.0.0 release.
akrupczynskirezolve Mar 20, 2026
77fafaf
Removed registration failed
denniskoluris Mar 24, 2026
52e3ac6
Added zoneID payload info
denniskoluris Mar 24, 2026
2d5758a
Merge branch 'main' into dk/push-notifications-ios
denniskoluris Mar 24, 2026
fcd6c78
BD-7149 Fix image paths.
akrupczynskirezolve Apr 7, 2026
33883a8
Minor changes after review
denniskoluris Apr 8, 2026
ec95e6a
Replaced with new canvas image
denniskoluris Apr 8, 2026
f217dc2
Added new image
denniskoluris Apr 8, 2026
15bcde1
Merge pull request #135 from Bluedot-Innovation/dk/push-notifications…
denniskoluris Apr 17, 2026
796f7e0
New navigation item for Push Notifications
denniskoluris Apr 17, 2026
ea7705f
Added Push Notifications product overview
denniskoluris Apr 17, 2026
4062d04
Minor changes/ordering
denniskoluris Apr 17, 2026
327cde2
Fix the path for the push module.
akrupczynskirezolve Apr 30, 2026
3e904e5
Merge pull request #137 from Bluedot-Innovation/ak/18.0.0-path-fix
akrupczynskirezolve May 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/Point SDK/Android/Overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ The following pages provide a guide to integrating the Point SDK with your Andro
* [Quick Start Guide](./Quick%20Start.md)
* [Geo-triggering](./Geo-triggering.md)
* [Tempo](./Tempo.md)
* [Push Notifications](./Push%20Notifications.md)
* [Location Permission & Notifications Best Practices](./Location%20Permission%20&%20Notifications%20Best%20Practices.md)
* [Best Practices & Recommendations](./Best%20Practices%20&%20Recommendations.md)
* [Guide to Submitting Apps With Location Services](../../Implementation%20and%20Best%20Practices%20Guides/Submitting%20apps%20with%20location%20services%20guide.md)
Expand All @@ -28,4 +29,5 @@ For further information on the classes and methods discussed within the followin

### Compatibility  Notes

* **Moshi:** Android PointSDK v15.0.0+ is compatible with Moshi up to 1.9.3.
* **Moshi:** Android PointSDK v15.0.0+ is compatible with Moshi up to 1.9.3.
* Since v18.0.0 the PointSDK is compiled using the Java 21 toolchain.
177 changes: 177 additions & 0 deletions docs/Point SDK/Android/Push Notifications.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
# Bluedot Push Notifications Module — Integration Guide

**SDK version:** 18.0.0
**Module artifact:** `au.com.bluedot:pushnotifications`

## Overview

Starting from version 18.0.0, push notification support is delivered as a **separate, optional module** — `pushnotifications`.

The module:
- Handles FCM token registration with the backend automatically.
- Displays notifications when a push message is received.
- Lets you customise the look of notifications.
- Provides callbacks for received and clicked notifications via a `PushNotificationsEventReceiver`.

## Requirements

| Requirement | Value |
|---|---|
| Min SDK | 29 (Android 10) |
| Compile SDK | 36 |
Comment thread
akrupczynskirezolve marked this conversation as resolved.
| Firebase Cloud Messaging | `com.google.firebase:firebase-messaging:25.0.1` |
| Core Point SDK | `au.com.bluedot:pointsdk:18.0.0` |

> Using non-compatible versions of the Firebase dependencies may lead to runtime crashes or unexpected behaviour.

## Prerequisites

Configure Android Push Notifications credentials and campaign in Canvas.

![](../../assets/canvas_push_settings_android.png)

Setup Push Notifications campaign in Canvas.

![](../../assets/canvas_push_campaign.png)

## Step 1 — Add the dependency

Follow [Quick Start](https://docs.bluedot.io/Point%20SDK/Android/Quick%20Start#import-the-sdk) guide to set up the core SDK first, including the project configuration URL and initialisation.

In your **app-level** `build.gradle`, add the `pushnotifications` module alongside the core SDK:

```groovy
dependencies {
// ...
implementation 'com.gitlab.bluedotio.android:point_sdk_push:18.0.0'
}
```

## Step 2 — Firebase setup

The `pushnotifications` module uses **Firebase Cloud Messaging (FCM)** to receive push notifications. If your app doesn't use Firebase yet, follow the [official Android documentation](https://firebase.google.com/docs/cloud-messaging/android/get-started) to set it up.

> On Android 13 (API 33) and above, you must declare `POST_NOTIFICATIONS` permission in your manifest **and** request it at runtime. Follow official [Android documentation](https://developer.android.com/training/permissions/requesting) for details.

## Step 3 — Implementation of FirebaseMessagingService

As part of Firebase Cloud Messaging integration you have implemented your own `FirebaseMessagingService` subclass. Now we are going to use it to bridge FCM events into the `pushnotifications` module.

```kotlin
class MyFirebaseMessagingService : FirebaseMessagingService() {

override fun onNewToken(token: String) {
ServiceManager.getInstance(this).pushNotificationsManager.onNewFcmToken(token)
}

override fun onMessageReceived(remoteMessage: RemoteMessage) {
// use convenient extension functions from the pushnotifications module to check if the message is from Rezolve and convert it to RezolvePushData
if (remoteMessage.isRezolvePushNotification()) {
ServiceManager.getInstance(this).pushNotificationsManager.onMessageReceived(remoteMessage.toRezolvePushData())
} else {
// Handle your own notifications here
}
}
}
```

Register the service in `AndroidManifest.xml`:

```xml
<service
android:name=".java.MyFirebaseMessagingService"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this supposed to show .java or the package string, like com.example.app?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can define this service class with full package name (com.example.app.java.MyFirebaseMessagingService) or skip the package name and leave just enough information for the compiler to be able to identify the class in your code (as above).

This example was taken straight from official Android docs: https://firebase.google.com/docs/cloud-messaging/android/receive-messages#edit-app-manifest

android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
```

## Step 4 — Listen for notification events

To receive callbacks when a notification is received or tapped by the user, create a `BroadcastReceiver` that extends `PushNotificationsEventReceiver`:

```kotlin
class MyPushNotificationsEventReceiver : PushNotificationsEventReceiver() {
override fun onNotificationReceived(rezolvePushData: RezolvePushData, context: Context) {
// Called when a Rezolve push notification arrives
// Use rezolvePushData.campaignId, .zoneId, .notificationId, .data
}

override fun onNotificationClicked(rezolvePushData: RezolvePushData, context: Context) {
// Called when the user taps the notification
}
}
```

Register the receiver in `AndroidManifest.xml`:

```xml
<receiver
android:name=".MyPushNotificationsEventReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="io.bluedot.point.PUSHNOTIFICATIONS" />
</intent-filter>
</receiver>
```

### NotificationData fields

| Field | Type | Description | Example value |
|---|---|---|------------------------------------------|
| `title` | `String` | Notification title (empty string if absent) | `"Title defined in Canvas Campaign"` |
| `body` | `String` | Notification body text (empty string if absent) | `"Body defined in Canvas Campaign"` |
| `pushVersion` | `String` | Push schema version | `"1.0"` |
| `campaignId` | `String` | Campaign UUID | `"b70e49c0-f12e-4ff1-b9f3-9d53767dc5b9"` |
| `zoneId` | `String` | Zone UUID | `"89060cba-a910-481a-aeb5-816182fdf01f"` |
| `notificationId` | `String` | Notification UUID | `"01J1ZQK8R4F9W6M0X9C1JZ7N2B"` |
| `data` | `Map<String, String>` | All remaining custom key-value pairs from the payload | `{"custom_key":"custom_value"}` |

---

## Step 5 — (Optional) Customise the notification appearance and behaviour

By default the module displays a standard notification using a built-in icon and the `IMPORTANCE_DEFAULT` channel.
On notification click the SDK sends the broadcast to the receiver defined in Step 4 and starts the default launcher activity defined for the app.

To override the appearance or behaviour, supply your own `NotificationCompat.Builder` **before** the first message arrives:

```kotlin
val channel = NotificationChannel(
CUSTOM_PUSH_CHANNEL_ID,
"Custom Push Notifications",
NotificationManager.IMPORTANCE_HIGH
)
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)

val contentIntent = PendingIntent.getActivity(
context,
0, // request code — unique integer to distinguish this PendingIntent from others;
// use different values if you create multiple distinct PendingIntents
Intent(context, YourCustomActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP
// Optionally pass data:
putExtra("my_custom_id", "1234")
},
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)

val customBuilder = NotificationCompat.Builder(context, CUSTOM_PUSH_CHANNEL_ID)
.setSmallIcon(R.drawable.your_notification_icon)
.setColor(ContextCompat.getColor(context, R.color.your_brand_color))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentIntent(contentIntent)
.setAutoCancel(true)

ServiceManager.getInstance(context)
.pushNotificationsManager
.setCustomPushNotification(customBuilder)
```

> PendingIntent is a system-managed token that dies with the process. Make sure to set the custom builder early in the app lifecycle (e.g. in Application.onCreate) so it is available when the first notification arrives. If the module receives a message before you set the custom builder, it will create and use a default one.

> The module fills in `.setContentTitle()` and `.setContentText()` automatically from the message payload, so you do not need to set them in your builder.

1 change: 1 addition & 0 deletions docs/Point SDK/iOS/Overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ The following pages provide a guide to integrating the Point SDK with your iOS a
* [Quick Start Guide](./Quick%20Start.md)
* [Geo-triggering](./Geo-triggering.md)
* [Tempo](./Tempo.md)
* [Push Notifications](./Push%20Notifications.md)
* [Location Permission best practices](./Location%20Permission%20Best%20Practices.md)
* [Guide to Submitting App With Location Services](../../Implementation%20and%20Best%20Practices%20Guides/Submitting%20apps%20with%20location%20services%20guide.md)
* [SDK Features](./Features/App%20restart%20notification.md)
Expand Down
Loading
Loading