View Categories

Mobile Integration (Flutter)

2 min read

This article explains how to perform a full integration of a mobile app written in Flutter.

Add the Releva Flutter SDK to your project #

Please add the following into your pubspec.yaml

dependencies:
  ...
  releva_sdk: '^0.0.32'
  ...

Initialize the Releva Client #

// realm - use '' unless instructed otherwise by your account manager
// <accessToken> - use the access token provided by your account manager
RelevaClient client = RelevaClient.customClient(
    '',
    '<yourAccessToken>'
);
// Please set the deviceId based on your current logic for device tracking
await client.setDeviceId('<deviceId>');

// If a user has registered or logged in, provide a profileId for this user. This must be consistent across channels and integrations
await client.setProfileId('<profileId>');

// enable app push notification engagement metrics collection (delivered, opened for push notifications sent through Releva)
// IMPORTANT: ensure that you have set the profileId and deviceId first!!

// OPTION 1: use the library's built-in callback registration
// IMPORTANT only do this if you DO NOT have ANY of the following anywhere in your app OR YOUR OTHER LIBRARIES:
// 1. FirebaseMessaging.instance.onMessage.listen((message) => ...);
// 2. FirebaseMessaging.instance.onMessageOpenedApp.listen((message) => ...);
// 3. FirebaseMessaging.instance.getInitialMessage().then((message) => ...);
await client.enablePushEngagementTracking();

OPTION 2: manually invoke Releva's engagement tracking in your hooks
Place the following code in your event hooks:
FirebaseMessaging.instance.onMessage.listen((message) async {
  ...
  await client.trackEngagement(message);
});

FirebaseMessaging.instance.onMessageOpenedApp.listen((message) async {
  ...
  await client.trackEngagement(message);
});

FirebaseMessaging.instance.getInitialMessage().then((message) async {
  ...
  await client.trackEngagement(message);
});

Send App Push Tokens #

// see possible DeviceType values - at the time of writing, there are android, ios, huawei, other
await client.registerPushToken(DeviceType.android, '<token>')

Add Push Activity Filter to your app’s Main Activity #

Add the following within your android/app/src/main/AndroidMainfest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application
        android:label="provider_shopper"
        android:name="${applicationName}"
        android:icon="@mipmap/ic_launcher">

        <activity
            android:name=".MainActivity"
            ...
           >

            <!-- ADDED for Releva -->
            <intent-filter>
                <action android:name="RELEVA_NOTIFICATION_CLICK" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

        ...
    </application>
</manifest>

Send a Push Request #

// If your app supports a wishlist feature set the active wishlist
// If the user has no wishlist right now, set it to an empty list
WishlistProduct product = WishlistProduct('<productId>', CustomFields.empty());
await client.setWishlist([product, ...]);

// create custom fields to pass to your cart product
CustomField<String> string = CustomField('size', ['S']);
CustomField<double> numeric = CustomField('size_code', [1,2]);
CustomField<DateTime> date = CustomField('in_promo_after', [DateTime.utc(2025, 1, 1, 0, 1, 2, 5)]);
CustomFields custom = CustomFields([string], [numeric], [date]);

// If your app supports a cart feature and the user set the active cart
// If the user has no cart right now, set it to a Cart.active instance with an empty list of products
CartProduct product = CartProduct('<id>', <price> as double, <quantity> as int, custom);
await client.setCart(Cart.active([product, ...]);

// initialize a request
PushRequest request = PushRequest()
  // if a user is viewing a screen with non-default language
  .locale('en')
  // if a user is viewing a screen with non-default currency
  .currency('EUR')
  // if the screen the user is viewing contains a list of items, and a filter is applied, set the filter
  .pageFilter(NestedFilter.and([]))
  // if a user is viewing a specific screen, and the screen (a.k.a. page) token
  .screenView('<pageToken>')
  // if a user is viewing a product, send the viewed product
  .productView(Viewedproduct('id', CustomFields.empty()))
  // if a user has performed custom events, for example filling out a form, send the custom event
  .customEvents([CustomEvent('fubar', [CustomEventProduct(item.id.toString(), 2)], ['foo_tag'], CustomFields.empty())]);

// send the request
await client.send(request);