Courier Flutter Overview
Courier.shared.isDebugging = true;
final userId = await Courier.shared.userId;
await Courier.shared.signIn(
accessToken: 'asdf...',
userId: 'example_user_id',
);
await Courier.shared.signOut();
Courier.shared.iOSForegroundNotificationPresentationOptions = [
iOSNotificationPresentationOption.banner,
iOSNotificationPresentationOption.sound,
iOSNotificationPresentationOption.list,
iOSNotificationPresentationOption.badge,
];
final currentPermissionStatus = await Courier.shared.getNotificationPermissionStatus();
final requestPermissionStatus = await Courier.shared.requestNotificationPermission();
await Courier.shared.setFcmToken(token: 'asdf...');
final fcmToken = await Courier.shared.fcmToken;
final apnsToken = await Courier.shared.apnsToken;
Courier.shared.onPushNotificationDelivered = (push) {
print(push);
};
Courier.shared.onPushNotificationClicked = (push) {
print(push);
};
final messageId = await Courier.shared.sendPush(
authKey: 'asdf...',
userId: 'example_user_id',
title: 'Hey! 👋',
body: 'Courier is awesome!!',
isProduction: false,
providers: [CourierProvider.apns, CourierProvider.fcm],
);
Requirements & Support
| Operating System | Min SDK | Compile SDK | Firebase Cloud Messaging | Apple Push Notification Service | Expo | OneSignal | Courier Inbox | Courier Toast |
|---|---|---|---|---|---|---|---|---|
iOS |
13 |
— | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
Android |
21 |
33 |
✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
Most of this SDK depends on a Courier account:
Create a Courier account here
Testing push notifications requires a physical device. Simulators will not work.
Installation
Link to
Example App
Install the packageiOS SetupAndroid SetupConfigure Push ProviderManaging User StateTesting Push Notifications
1. Install the package
Run the following command at your project's root directory:
flutter pub add courier_flutter
2. iOS Setup
If you don't need push notification support on iOS, you can skip this step.
https://user-images.githubusercontent.com/6370613/198094477-40f22b1e-b3ad-4029-9120-0eee22de02e0.mov
- Open your iOS project and increase the min SDK target to iOS 13.0+
- From your Flutter project's root directory, run:
cd ios && pod update - Change your
AppDelegateto extend theCourierFlutterDelegateand addimport courier_flutterto the top of yourAppDelegatefile- This automatically syncs APNS tokens to Courier
- Allows the Flutter SDK to handle when push notifications are delivered and clicked
- Enable the "Push Notifications" capability
Add the Notification Service Extension (Recommended)
To make sure Courier can track when a notification is delivered to the device, you need to add a Notification Service Extension. Here is how to add one.
- Download and Unzip the Courier Notification Service Extension:
CourierNotificationServiceTemplate.zip - Open the folder in terminal and run
sh make_template.sh- This will create the Notification Service Extension on your mac to save you time
- Open your iOS app in Xcode and go to File > New > Target
- Select "Courier Service" and click "Next"
- Give the Notification Service Extension a name (i.e. "CourierService"), select
Courier_iOSas the Package, and click "Finish" - Click "Cancel" on the next popup
- You do NOT need to click "Activate" here. Your Notification Service Extension will still work just fine.
- Select Service Extension (i.e. "CourierService"), select general, change deployment sdk to min SDK target to iOS 13.0+
- Open your
Podfileand add the following snippet to the end of your Podfile- This will link the
Courier-iOSpod to your Notification Service Extension
- This will link the
target 'CourierService' do
use_frameworks!
pod 'Courier-iOS'
end
- From the root of your Flutter app, run:
cd ios && pod install
3. Android Setup
If you don't need push notification support on Android, you can skip this step.
https://user-images.githubusercontent.com/6370613/198111372-09a29aba-6507-4cf7-a59d-87e8df2ba492.mov
- Open Android project
- Add support for Jitpack to
android/build.gradle- This is needed because the Courier Android SDK is hosted using Jitpack
- Maven Central support will be coming later
allprojects {
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' } // Add this line
}
}
- Update your
app/build.gradleto support the min and compile SDKsminSdkVersion 21compileSdkVersion 33
- Run Gradle sync
- Change your
MainActivityto extend theCourierFlutterActivity- This allows Courier to handle when push notifications are delivered and clicked
- Setup a new Notification Service by creating a new file and pasting the code below in it
- This allows you to present a notification to your user when a new notification arrives
import android.annotation.SuppressLint
import com.courier.android.notifications.presentNotification
import com.courier.android.service.CourierService
import com.google.firebase.messaging.RemoteMessage
// This is safe. `CourierService` will automatically handle token refreshes.
@SuppressLint("MissingFirebaseInstanceTokenRefresh")
class YourNotificationService: CourierService() {
override fun showNotification(message: RemoteMessage) {
super.showNotification(message)
// TODO: This is where you will customize the notification that is shown to your users
// The function below is used to get started quickly.
// You likely do not want to use `message.presentNotification(...)`
// For Flutter, you likely do not want to change the handlingClass
// More information on how to customize an Android notification here:
// https://developer.android.com/develop/ui/views/notifications/build-notification
message.presentNotification(
context = this,
handlingClass = MainActivity::class.java,
icon = android.R.drawable.ic_dialog_info
)
}
}
- Add the Notification Service entry in your
AndroidManifest.xmlfile
<manifest>
<application>
<activity>
..
</activity>
// Add this 👇
<service
android:name=".YourNotificationService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
// Add this 👆
..
</application>
</manifest>
4. Configure Push Provider
If you don't need push notification support, you can skip this step.
To get push notification to appear in your app, add support for the provider you would like to use:
5. Managing User State
Best user experience practice is to synchronize the current user's push notification tokens and the user's state. Courier does most of this for you automatically!
You can use a Courier Auth Key
found herewhen developing.
When you are ready for production release, you should be using a JWT as the
accessToken. Here is more info aboutGoing to Production
Place these functions where you normally manage your user's state:
// Saves accessToken and userId to native level local storage
// This will persist between app sessions
await Courier.shared.signIn(
accessToken: accessToken,
userId: userId,
);
await Courier.shared.signOut();
If you followed the steps above:
- APNS tokens on iOS will automatically be synced to Courier
- FCM tokens on Android will automatically be synced to Courier
If you want FCM tokens to sync to Courier on iOS:
-
Add the following Flutter packages to your project
-
Add code to manually sync FCM tokens
final fcmToken = await FirebaseMessaging.instance.getToken();
if (fcmToken != null) {
await Courier.shared.setFcmToken(token: fcmToken);
}
// Handle FCM token refreshes
FirebaseMessaging.instance.onTokenRefresh.listen((fcmToken) {
Courier.shared.setFcmToken(token: fcmToken);
});
6. Testing Push Notifications
If you don't need push notification support, you can skip this step.
Courier allows you to send a push notification directly from the SDK to a user id. No tokens juggling or backend needed!
final notificationPermission = await Courier.shared.getNotificationPermissionStatus();
print(notificationPermission);
// Notification permissions must be `authorized` on iOS to receive pushes
final requestedNotificationPermission = await Courier.shared.requestNotificationPermission();
print(requestedNotificationPermission);
// This is how iOS will show the notification when the app is in the foreground
// Passing [] will not present anything
// `Courier.shared.onPushNotificationDelivered` will still get called
Courier.shared.iOSForegroundNotificationPresentationOptions = [
iOSNotificationPresentationOption.banner,
iOSNotificationPresentationOption.sound,
iOSNotificationPresentationOption.list,
iOSNotificationPresentationOption.badge,
];
// Will be called if the app is in the foreground and a push notification arrives
Courier.shared.onPushNotificationDelivered = (push) {
...
};
// Will be called when a user clicks a push notification
Courier.shared.onPushNotificationClicked = (push) {
...
};
// Sends a test push
final messageId = await Courier.shared.sendPush(
authKey: 'a_courier_auth_key_that_should_only_be_used_for_testing',
userId: 'example_user',
title: 'Chirp Chrip!',
body: 'Hello from Courier 🐣',
isProduction: false, // This only affects APNS pushes. false == sandbox / true == production
providers: [CourierProvider.apns, CourierProvider.fcm],
);
Going to Production
For security reasons, you should not keep your authKey (which looks like: pk_prod_ABCD...) in your production app. The authKey is safe to test with, but you will want to use an accessToken in production.
To create an accessToken, call this:
curl --request POST \
--url https://api.courier.com/auth/issue-token \
--header 'Accept: application/json' \
--header 'Authorization: Bearer $YOUR_AUTH_KEY' \
--header 'Content-Type: application/json' \
--data
'{
"scope": "user_id:$YOUR_USER_ID write:user-tokens",
"expires_in": "$YOUR_NUMBER days"
}'
Or generate one here:
Issue Courier Access Token
This request to issue a token should likely exist in a separate endpoint served on your backend.
Share feedback with Courier
We want to make this the best SDK for managing notifications! Have an idea or feedback about our SDKs? Here are some links to contact us: