beaconsmind_sdk 1.8.0 copy "beaconsmind_sdk: ^1.8.0" to clipboard
beaconsmind_sdk: ^1.8.0 copied to clipboard

Beaconsmind SDK for Flutter

Beaconsmind SDK #

Beaconsmind SDK for Flutter.

Prerequisites #

As a Beaconsmind client, a contained environment is provided for Beaconsmind services being hosted and maintained by Beaconsmind.

The hostname of the provided environment is required to properly access Beaconsmind API and to use Beaconsmind SDK

example: https://adidas.bms.beaconsmind.com

Please contact Beaconsmind support for the required information about acquiring a valid environment and hostname.

1. Installing #

Add beaconsmind_sdk to your app pubspec.yaml.

2. Platform setup #

iOS #

Please follow this guide to properly setup iOS platform.

Android #

Please follow this guide to properly setup Android platform.

2. Initialize the SDK #

This will initialize the SDK, and try to retrieve the logged-in user.

await Beaconsmind.instance.initialize(
  hostname: 'https://test-develop-suite.azurewebsites.net/',
  appVersion: '1.0.0',
  androidNotificationBadgeName: 'ic_beacons',
  androidNotificationChannelName: 'beaconsmind',
  androidNotificationTitle: 'Beaconsmind sdk demo',
  androidNotificationText: 'Listening to beacons',
);

3. Permissions #

Beaconsmind SDK requires bluetooth and location (whenInUse or always) permissions to detect nearby beacon devices and notification permission to send offers.

In order to request required permissions, consider using the permission_handler package. Make sure to follow the setup required for native iOS & Android.


For testing purposes, consider using Beaconsmind.initializeDevelop() in order to initialize and automatically ask the user for all permissions at once that are required for Beaconsmind SDK to work properly. Make sure to follow the platform setup that is required for it to work:

Android #

  1. Change the MainActivity.kt file to extend FlutterFragmentActivity instead of FlutterActivity.

    import io.flutter.embedding.android.FlutterActivity
    import io.flutter.embedding.android.FlutterFragmentActivity
    
    class MainActivity: FlutterFragmentActivity() {
    }
    
  2. Use descendant of Theme.AppCompat for your activity theme (both light and dark). These changes are needed because the Beaconsmind SDK requires the use of the AppCompat theme for the permission dialog.

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
        <style name="LaunchTheme" parent="Theme.AppCompat.Light.NoActionBar">
            <!-- Show a splash screen on the activity. Automatically removed when
                Flutter draws its first frame -->
            <item name="android:windowBackground">@drawable/launch_background</item>
        </style>
        <!-- Theme applied to the Android Window as soon as the process has started.
            This theme determines the color of the Android Window while your
            Flutter UI initializes, as well as behind your Flutter UI while its
            running.
            This Theme is only used starting with V2 of Flutter's Android embedding. -->
        <style name="NormalTheme" parent="Theme.MaterialComponents">
            <item name="android:windowBackground">?android:colorBackground</item>
        </style>
    </resources>
    

iOS #

Make sure to add the following key to your Info.plist file, located in

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>$(PRODUCT_NAME) needs access to your location to detect beacons.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>$(PRODUCT_NAME) needs access to your location to detect beacons.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>$(PRODUCT_NAME) needs access to your location to detect beacons.</string>

4. Authentication #

When using Beaconsmind authentication #

This approach implies that the customer data is kept in Beaconsmind backend. Use UserManager.login method to perform customer authentication.

To login existing user.

try {
  final user = await Beaconsmind.instance.login(
    username: _usernameController.text,
    password: _passController.text,
  );
} catch (e) {
  final snackBar = SnackBar(
    content: Text(e.toString()),
  );
  ScaffoldMessenger.of(context).showSnackBar(snackBar);
}

To register a new user.

try {
  final user = await Beaconsmind.instance.signup(
    username: _emailController.text,
    firstName: _firstNameController.text,
    lastName: _lastNameController.text,
    password: _passController.text,
    confirmPassword: _passConfirmController.text,
  );
  Navigator.of(context).pop();
} catch (e) {
  final snackBar = SnackBar(
    content: Text(e.toString()),
  );
  ScaffoldMessenger.of(context).showSnackBar(snackBar);
}

When using own authentication mechanism #

This approach implies that the customer data is kept in clients backend. The authentication is done by the client app before the Beaconsmind API is used. Whenever customer is authenticated, use Beaconsmind.instance.importAccount method to send basic customer data to Beaconsmind. The customer data is updated only the first time the method is called. The client app can track if the customer was imported before and omit personal data from following importAccount calls.

5. Listening to SDK context changes #

The SDK provides a Stream for the user login/logout changes. Beaconsmind.instance.contextEvents()

Beaconsmind.instance.contextEvents().listen((BeaconsmindSdkContext? event) {
    // When event is null, the user is not logged in.
    // When the event is no nill, the user is logged in.
});

6. Notifications #

The SDK uses APNS for iOS, and Firebase for Android. You will need to use two packages from pub. firebase_messaging & flutter_apns.

Setting device token #

Check with Beaconsmind support team which push notification provider is used for Android and iOS.

If FCM is used for both Android and iOS, register the device token using the code snippet below.

String? fcmToken = await FirebaseMessaging.instance.getToken();
await Beaconsmind.registerDeviceToken(
  token: fcmToken,
  platformType: PlatformType.fcm
);

If FCM is used for Android and APNS is used for iOS, register device token using the code snippet below.

if (Platform.isAndroid) {
  final fcmToken = await FirebaseMessaging.instance.getToken();
  if (fcmToken != null) {
    await Beaconsmind.instance.registerDeviceToken(
      deviceToken: fcmToken,
      platformType: PlatformType.fcm,
    );
  }
}

if (Platform.isIOS) {
  final apnsToken = await getApnsToken()
  if (apnsToken != null) {
    await Beaconsmind.instance.registerDeviceToken(
      deviceToken: apnsToken,
      platformType: PlatformType.apns,
    );
  }
}

Supporting multiple push notification providers #

Issue

On Android, if there is more than one package used to receive push notifications, for example: moengage_flutter & firebase_messaging, then only one package will be notified about a push notification.

Explanation

Each package used to receive push notifications has it’s on AndroidManifest.xml file (manifest) where it declares a service that should receive and handle the FCM messages — here is an example from the firebase_messaging package.

When app is built, the app’s manifest is merged with each manifest from packages that it depends on. As a result, the final manifest will contain multiple services declared to receive FCM messages, but the system will deliver push notification only to one of them, the one that is declared earlier.

If there is a service declaration at the app’s manifest, then it will take a precedence over service declarations from packages’ manifest.

Solution

In order to deliver push notifications to services declared by each package, a proxy service declared at the app’s manifest needs to be introduced. It will be responsible for intercepting push notifications and forwarding them to other services coming from used packages.

Implementation

  1. Add FirebaseMessagingServiceProxy.kt file to your Android app project.
  2. In the FirebaseMessagingServiceProxy file, update messagingServices list with push notification services that you want to notify. Make sure to add necessary imports at the top of the file in order to access them.
  3. Register the FirebaseMessgingServiceProxy in the app’s manifest.

7. Offers #

Getting offers #

  • loadOffer({required int id}). Will return a single offer.
  • loadOffers(). Will return a list of currently active offers.

Interacting with offers #

  • markOfferAsReceived({required int offerId}). Call this when an ofer is received via push.
  • markOfferAsRead({required int offerId}). Call this when the user open the offer.
  • markOfferAsRedeemed({required int offerId}). Call this when the user redeems the offer.

8. Beacons #

Interacting with beacons #

  • startListeningBeacons().
  • stopListeningBeacons().
  • getBeaconsSummary().

Read more about beacons #

7. Disposing #

Call Beaconsmind.instance.dispose(); to clean app resources and prevent memory leaks.

Platform specifics #

Android #

If using proguard with Beaconsmind Android SDK versions prior to 1.7.0 add a custom rule to your proguard-rules.pro:

  • -keep class com.beaconsmind.api.models** { *; }