Skip to contentSkip to navigationSkip to topbar
Rate this page:
On this page

Registering for Notifications on Android


Ready to send your first notification? We'll get you registered so you can start sending notifications faster than a collision-free hash table lookup (OK, maybe not that fast).

A Notifications application involves two components:

  • A client (Android) app that registers for and receives notifications
  • A server app that creates bindings and sends notifications

The aim of this guide is to show you how to store the app's unique address in Notify by creating a Binding so that later we can send notifications to it. There are two cases when you would need to update the Binding in Notify:

  • when the user logs in for the first time or with a new Identity
  • when FCM changes the address of the app.

As both acquiring the address of the app and creating a binding may take a bit, it is best to implement registration in a dedicated service (e.g., RegistrationIntentService) and fire it in both scenarios. Let's start with the first scenario, logging a new user in and then adding support for changing addresses.

When a user logs in, you want to capture the Identity and fire the RegistrationIntentService passing the new Identity as an Extra. Let's take a look at then how this RegistrationIntentService works.

First, the RegistrationIntentService needs to acquire the address of the app, and the registration token. This is done by invoking the FirebaseInstanceId.getInstance().getToken(); method.

Register a Device

register-a-device page anchor

_10
public class RegistrationIntentService extends IntentService {
_10
@Override
_10
protected void onHandleIntent(Intent intent) {
_10
String token = FirebaseInstanceId.getInstance().getToken();
_10
}
_10
}

Next, we need to get the Identity from the extra and create a Binding in Twilio. A "Binding" represents a unique app installation that can receive a notification. It associates a registration token (that we just acquired) with an Identity (from the Intent Extra). You can use the Identity to send notifications to a specific user (Identity). (More on that later.)

The app should send a request to the server containing the registration token, Identity, and BindingType. The server then will use this information to create the Binding via the Twilio API. We add this indirection to avoid exposing our Twilio credentials in the Android app.

Create a Binding (Client-side)

create-a-binding-client-side page anchor

_36
public class RegistrationIntentService extends IntentService {
_36
private BindingResource bindingResource;
_36
_36
@Override
_36
protected void onHandleIntent(Intent intent) {
_36
String token = FirebaseInstanceId.getInstance().getToken();
_36
String identity = intent.getStringExtra(IDENTITY);
_36
String storedIdentity = sharedPreferences.getString(IDENTITY, null);
_36
if (newIdentity == null) {
_36
// If no identity was provided to us then we use the identity stored in shared preferences.
_36
// This can occur when the registration token changes.
_36
identity = storedIdentity;
_36
} else {
_36
// Otherwise we save the new identity in the shared preferences for future use.
_36
sharedPreferences.edit().putString(IDENTITY, binding.identity).commit();
_36
}
_36
sendRegistrationToServer(identity, token);
_36
}
_36
_36
@Override
_36
public void onCreate(){
_36
super.onCreate();
_36
Retrofit retrofit = new Retrofit.Builder()
_36
.baseUrl(AppConstants.BASE_URL).addConverterFactory(JacksonConverterFactory.create(new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL)))
_36
.build();
_36
bindingResource = retrofit.create(BindingResource.class);
_36
}
_36
_36
private CreateBindingResponse sendRegistrationToServer(String identity, String token) throws IOException {
_36
String endpoint = sharedPreferences.getString(ENDPOINT + newIdentity, null);
_36
Binding binding = new Binding(identity, endpoint, token, "fcm");
_36
Call<CreateBindingResponse> call = bindingResource.createBinding(binding);
_36
Response<CreateBindingResponse> response = call.execute();
_36
sharedPreferences.edit().putString(ENDPOINT + binding.identity, response.body().endpoint).commit();
_36
}
_36
}

We use retrofit2 to make this request, but you can use any HTTP client. Our mini-API to communicate with our server is defined in the BindingResource, Binding and CreateBindingResponse classes. The BindingResource interface defines the signature of our simple API.

Create a Binding (Client-side)

create-a-binding-client-side-1 page anchor

_10
public interface BindingResource {
_10
@POST("/register")
_10
Call<CreateBindingResponse> createBinding(@Body Binding binding);
_10
}

The Binding class is a simple Plain Old Java Object (POJO) that the retrofit2 API will translate to JSON for us. It wraps the parameters we need to send to the server.

Create a Binding (Client-side)

create-a-binding-client-side-2 page anchor

_13
public class Binding {
_13
public String identity;
_13
public String endpoint;
_13
public String Address;
_13
public String BindingType;
_13
_13
public Binding(String identity, String endpoint, String address, String bindingType) {
_13
this.identity = identity;
_13
this.endpoint = endpoint;
_13
Address = address;
_13
BindingType = bindingType;
_13
}
_13
}

The CreateBindingResponse is another POJO to translate the server's JSON response including the generated endpoint identifier and a message in case something went wrong.

Create a Binding (Client-side)

create-a-binding-client-side-3 page anchor

_25
package com.twilio.notify.quickstart.notifyapi.model;
_25
_25
/**
_25
* Created by vmuller on 4/19/17.
_25
*/
_25
public class CreateBindingResponse {
_25
public String message;
_25
public String endpoint;
_25
_25
public String getMessage() {
_25
return message;
_25
}
_25
_25
public String getEndpoint() {
_25
return endpoint;
_25
}
_25
_25
public void setMessage(String message) {
_25
this.message = message;
_25
}
_25
_25
public void setEndpoint(String endpoint) {
_25
this.endpoint = endpoint;
_25
}
_25
}

We are almost finished with the Android app. Remember that there was another scenario when we wanted to create a Binding: when FCM changed the registration token. To implement this, we will need two simple steps:

  • Register a service that listens to the token update events from FCM
  • Implement that service

To register the service, we'll add an intent filter to declare the capabilities of our service, the MyInstanceIDService.

Create a Binding (Client-side)

create-a-binding-client-side-4 page anchor

_10
<service android:name="[.MyInstanceIDService]" android:exported="false">
_10
<intent-filter>
_10
<action android:name="com.google.android.gms.iid.InstanceID"/>
_10
</intent-filter>
_10
</service>

Then we can implement this very simple service. All it does is, invoke our RegistrationIntentService to create a new Binding.

You may wonder, how can we just keep creating Bindings without ever deleting any? The Notify API's deduplication feature allows this. It deletes previous Bindings in the same Notify Service that have the same Address (registration token) or Endpoint. Endpoint is an auto-generated unique identifier that we receive from the Notify service. Notice how our SendRegistrationToServer method stores this Endpoint in the shared preferences and reuses it in subsequent create Binding requests ensuring that Bindings are not duplicated even when the registration token changes.


Server

server page anchor

Now that we have our Android app ready, let's turn our attention to the server that interacts with the Notify API.

In our server app, we'll receive the POST request. It will contain the following four parameters.

namedescription
IdentityThe Identity to which this Binding belongs. Identity is defined by your application and can have multiple endpoints.
EndpointThe identifier of the device to which this registration belongs. Endpoints are also defined by your application.
BindingTypeThe type of the Binding determines the transport technology to use.
AddressThe address obtained from the vendor. For APNS it is the device token. For FCM, it is the registration token.
(error)

Danger

Do not use Personally Identifiable Information for Identity

Notify uses Identity as a unique identifier of a user. You should not use directly identifying information (aka personally identifiable information or PII) like a person's name, home address, email or phone number, etc. as Identity, because the systems that will process this attribute assume it is not directly identifying information.

We'll use index.js in our server app and these four parameters to send an API request to Twilio. Then, we'll send a success message or an error back to the mobile app together with the Endpoint. We implement this logic in the /register endpoint, but this is not required. You can come up with your own API, and perhaps integrate it into a login or a session initialization flow.

Create a Binding (Server-side)

create-a-binding-server-side page anchor
Node.js
Python
C#
Java
Go
PHP
Ruby
twilio-cli
curl

_17
// Download the helper library from https://www.twilio.com/docs/node/install
_17
// Find your Account SID and Auth Token at twilio.com/console
_17
// and set the environment variables. See http://twil.io/secure
_17
const accountSid = process.env.TWILIO_ACCOUNT_SID;
_17
const authToken = process.env.TWILIO_AUTH_TOKEN;
_17
const client = require('twilio')(accountSid, authToken);
_17
_17
client.notify.v1.services('ISXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
_17
.bindings
_17
.create({
_17
endpoint: 'XXXXXXXXXXXXXXX',
_17
tag: ['preferred device'],
_17
identity: '00000001',
_17
bindingType: 'fcm',
_17
address: 'fcm_device_token'
_17
})
_17
.then(binding => console.log(binding.sid));

Output

_20
{
_20
"account_sid": "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
_20
"address": "fcm_device_token",
_20
"binding_type": "fcm",
_20
"credential_sid": null,
_20
"date_created": "2015-07-30T20:00:00Z",
_20
"date_updated": "2015-07-30T20:00:00Z",
_20
"endpoint": "XXXXXXXXXXXXXXX",
_20
"identity": "00000001",
_20
"notification_protocol_version": "3",
_20
"service_sid": "ISXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
_20
"sid": "BSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
_20
"tags": [
_20
"26607274"
_20
],
_20
"links": {
_20
"user": "https://notify.twilio.com/v1/Services/ISXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Users/24987039"
_20
},
_20
"url": "https://notify.twilio.com/v1/Services/ISXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Bindings/BSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
_20
}

Now that we've registered the client app with Firebase Cloud Messaging and created a Binding, it's time to send some notifications! Check out our Sending Notifications guide for more information.

Next: Sending Notifications »


Rate this page: