SDK

Device Registration

In this guide we will dive deeper into how you should handle the device registration. When you launch() Notificare, the device will be registered as a non-push device.

When a successful device registration takes place, we will emit an intent. If you have configured a custom intent receiver as mentioned in the Implementation page, you can receive those intents by overriding the onDeviceRegistered() method from NotificareIntentReceiver.

class CustomIntentReceiver : NotificareIntentReceiver() {

    override fun onDeviceRegistered(context: Context, device: NotificareDevice) {

    }
}
class CustomIntentReceiver extends NotificareIntentReceiver {

    @Override
    protected void onDeviceRegistered(@NonNull Context context, @NonNull NotificareDevice device) {

    }
};

You can also check the details of the currently registered device.

Notificare.device().currentDevice
NotificareDeviceCompat.getCurrentDevice();

The onReady() method in NotificareIntentReceiver will also be called when all Notificare modules has been launched, including a successful device registration.

Additionally, you can verify whether Notificare is ready at any point by calling Notificare.isReady or listen to the onReady event anywhere in your code by adding a Notificare.OnReadyListener as described below.

class MainActivity : AppCompatActivity(), Notificare.Listener {

    override fun onCreate(savedInstanceState: Bundle?) {
        // more code ...

        Notificare.addListener(this)
    }

    override fun onDestroy() {
        // more code ...

        Notificare.removeListener(this)
    }

    // region Notificare.OnReadyListener

    override fun onReady(application: NotificareApplication) {

    }

    override fun onUnlaunched() {

    }

    // endregion

}
public class MainActivity extends AppCompatActivity implements Notificare.Listener {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        // more code ...

        Notificare.addListener(this);
    }

    @Override
    protected void onDestroy() {
        // more code ...

        Notificare.removeListener(this);
    }

    // region Notificare.OnReadyListener

    @Override
    public void onReady(@NonNull NotificareApplication application) {

    }

    @Override
    public void onUnlaunched() {

    }

    // endregion

}

Register as a user

By default, a device is registered as an anonymous user. However, there will be situations where simply registering an anonymous device is not what you want. For example if you authenticate your users you will not want to register an anonymous device whenever the app launches. When that is the case, you will need to tell the library you want to register as a specific user.

Notificare.device().register(
    userId = "7f42bedc-d74b-4c64-a5cf-76bcc5130b05",
    userName = "John Doe",
    callback = object : NotificareCallback<Unit> {
        override fun onSuccess(result: Unit) {

        }

        override fun onFailure(e: Exception) {

        }
    }
)
String userId = "7f42bedc-d74b-4c64-a5cf-76bcc5130b05";
String userName = "John Doe";

NotificareDeviceCompat.register(userId, userName, new NotificareCallback<Unit>() {
    @Override
    public void onSuccess(Unit result) {

    }

    @Override
    public void onFailure(@NonNull Exception e) {

    }
});

After that, the device will remain registered with that userId / userName until you explicitly register it as anonymous. Depending on the way you authenticate users, you might want to check the logged in state on launch (in the onReady) and change it if necessary. Forcing registration as anonymous can be best achieved by setting userId and userName to null.

Notificare.device().register(
    userId = null,
    userName = null,
    callback = object : NotificareCallback<Unit> {
        override fun onSuccess(result: Unit) {

        }

        override fun onFailure(e: Exception) {

        }
    }
)
String userId = null;
String userName = null;

NotificareDeviceCompat.register(userId, userName, new NotificareCallback<Unit>() {
    @Override
    public void onSuccess(Unit result) {

    }

    @Override
    public void onFailure(@NonNull Exception e) {

    }
});

Override Device Language

By default, we will automatically collect the language and region of a device based on the Locale of the device. For most cases this will be enough but for those cases where you would like to override the device language and region combination to a strict selection of languages, you can do so by invoking the following method:

Notificare.device().updatePreferredLanguage("en-US", object : NotificareCallback<Unit> {
    override fun onSuccess(result: Unit) {

    }

    override fun onFailure(e: Exception) {

    }
})
NotificareDeviceCompat.updatePreferredLanguage("en_US", new NotificareCallback<Unit>() {
    @Override
    public void onSuccess(Unit result) {

    }

    @Override
    public void onFailure(@NonNull Exception e) {

    }
});

Eventually, you can always retrieve the preferred language by calling the following method:

Notificare.device().preferredLanguage
NotificareDeviceCompat.getPreferredLanguage();

User Data Fields

There are use cases where simply associating an userId and userName will not suffice. For those cases you can make use of User Data Fields where you can create key-value pairs for your application and then use them to extend your device registration. Before you can implement them you will need to first create them in your application via our dashboard. This is described here.

Once you have created one or more fields, you can implement this functionality in your app. To retrieve the list of fields allowed in your app you should use the following method:

Notificare.device().fetchUserData(object : NotificareCallback<NotificareUserData> {
    override fun onSuccess(result: NotificareUserData) {

    }

    override fun onFailure(e: Exception) {

    }
})
NotificareDeviceCompat.fetchUserData(new NotificareCallback<Map<String, String>>() {
    @Override
    public void onSuccess(Map<String, String> result) {

    }

    @Override
    public void onFailure(@NonNull Exception e) {

    }
});

Whenever you want to update those fields with new values you should use the following method:

val userData: NotificareUserData = mapOf(
    /* your properties here */
    "myKey" to "myValue",
)

Notificare.device().updateUserData(userData, object : NotificareCallback<Unit> {
    override fun onSuccess(result: Unit) {

    }

    override fun onFailure(e: Exception) {

    }
})
Map<String, String> userData = new HashMap<>();
/* populate the Map with your properties */

NotificareDeviceCompat.updateUserData(userData, new NotificareCallback<Unit>() {
    @Override
    public void onSuccess(Unit result) {

    }

    @Override
    public void onFailure(@NonNull Exception e) {

    }
});

If you are using our inbox functionality, these fields will also be available as placeholders when sending notifications by simply including {{userData.key}} in your messages.

Do Not Disturb

Each device registered with Notificare can be configured to specify a period of time during the day when it should not receive notifications. You can use this functionality in your app settings to allow the user to provide a time range where messages will not be displayed in the lock screen or notification center. Please note that if you are using our inbox functionality these message will still be there.

To retrieve a device's DnD preferences use the following method:

Notificare.device().fetchDoNotDisturb(object: NotificareCallback<NotificareDoNotDisturb?> {
    override fun onSuccess(result: NotificareDoNotDisturb?) {

    }

    override fun onFailure(e: Exception) {

    }
})
NotificareDeviceCompat.fetchDoNotDisturb(new NotificareCallback<NotificareDoNotDisturb>() {
    @Override
    public void onSuccess(NotificareDoNotDisturb result) {

    }

    @Override
    public void onFailure(@NonNull Exception e) {

    }
});

You can update the DnD values for a device, using the following method:

Notificare.device().updateDoNotDisturb(dnd, object : NotificareCallback<Unit> {
    override fun onSuccess(result: Unit) {

    }

    override fun onFailure(e: Exception) {

    }
})
NotificareDeviceCompat.updateDoNotDisturb(dnd, new NotificareCallback<Unit>() {
    @Override
    public void onSuccess(Unit result) {

    }

    @Override
    public void onFailure(@NonNull Exception e) {

    }
});

Finally, you will probably also need to eventually clear the Do Not Disturb period. To do that, simply use the method below:

Notificare.device().clearDoNotDisturb(object : NotificareCallback<Unit> {
    override fun onSuccess(result: Unit) {

    }

    override fun onFailure(e: Exception) {

    }
})
NotificareDeviceCompat.clearDoNotDisturb(new NotificareCallback<Unit>() {
    @Override
    public void onSuccess(Unit result) {

    }

    @Override
    public void onFailure(@NonNull Exception e) {

    }
});

Test Devices

It is possible to enable devices to be registered as test devices. This allows you to perform a wide range of tests in our dashboard by simply scanning a QR Code. In order to enable this functionality, the following steps are mandatory.

First you need to add the following URL scheme to your app's AndroidManifest.xml:

<activity android:name=".MainActivity">

    <!-- ... existing intent filters    -->

    <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.VIEW" />

        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />

        <data
            android:host="${notificareAppId}.applinks.notifica.re"
            android:pathPrefix="/testdevice"
            android:scheme="https" />
    </intent-filter>

</activity>

Where ${notificareAppId} must be replaced by your own app identifier (you can find that in Settings > Configure App).

When dealing with a multi-environment application, you may want to consider using your build.gradle to configure the manifestPlaceholders.

Then inside the intent handling routine in your MainActivity, you will need to handle possible intents to that URL scheme.

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // more code ...

    if (intent != null) handleIntent(intent)
}

override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
    // more code ...

    if (intent != null) handleIntent(intent)
}

private fun handleIntent(intent: Intent) {
    if (Notificare.handleTestDeviceIntent(intent)) {
        Log.d(TAG, "Test device intent handled.")
        return
    }

    // more code ...
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // more code ...

    if (getIntent() != null) handleIntent(getIntent());
}

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    // more code ...

    if (intent != null) handleIntent(intent);
}

private void handleIntent(Intent intent) {
    if (Notificare.handleTestDeviceIntent(intent)) {
        Log.d(TAG, "Test device intent handled.");
        return;
    }

    // more code ...
}

The method will return true if the intent could be parsed as a Test Device registration intent. If it returns false, this means you should process the intent yourself.

Since the Test Devices links are Dynamic Links, you must configure the Links service, providing information about your application identifier and fingerprints. You can find more information in the Links guide.