# Registering for Notifications on Android

> \[!CAUTION]
>
> Twilio deprecated Notify in October 2022 and no longer supports it. Learn more about [transitioning off Notify](https://support.twilio.com/hc/en-us/articles/11746930233115-Transitioning-off-Notify).
>
> If you're starting a new project, use [Programmable Messaging](/docs/messaging) for SMS notifications. For push notifications, integrate directly with platform-specific services such as APNs for iOS or FCM for Android. If you've already built on Notify, visit the [transition guide](https://support.twilio.com/hc/en-us/articles/11746930233115-Transitioning-off-Notify) to learn about your options.

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.

```java title="Register a Device"
public class RegistrationIntentService extends IntentService {
  @Override
  protected void onHandleIntent(Intent intent) {
    String token = FirebaseInstanceId.getInstance().getToken();
  }
}
```

Next, we need to get the Identity from the extra and create a [Binding](/docs/notify/api/binding-resource) 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.

```java title="Create a Binding (Client-side)"
public class RegistrationIntentService extends IntentService {
  private BindingResource bindingResource;

  @Override
  protected void onHandleIntent(Intent intent) {
    String token = FirebaseInstanceId.getInstance().getToken();
    String identity =  intent.getStringExtra(IDENTITY);
    String storedIdentity = sharedPreferences.getString(IDENTITY, null);
    if (newIdentity == null) {
      // If no identity was provided to us then we use the identity stored in shared preferences.
      // This can occur when the registration token changes.
      identity = storedIdentity;
    } else {
      // Otherwise we save the new identity in the shared preferences for future use.
      sharedPreferences.edit().putString(IDENTITY, binding.identity).commit();
    }
    sendRegistrationToServer(identity, token);
  }

  @Override
  public void onCreate(){
      super.onCreate();
      Retrofit retrofit = new Retrofit.Builder()
              .baseUrl(AppConstants.BASE_URL).addConverterFactory(JacksonConverterFactory.create(new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL)))
              .build();
      bindingResource = retrofit.create(BindingResource.class);
  }

  private CreateBindingResponse sendRegistrationToServer(String identity, String token) throws IOException {
    String endpoint = sharedPreferences.getString(ENDPOINT + newIdentity, null);
    Binding binding = new Binding(identity, endpoint, token, "fcm");
    Call<CreateBindingResponse> call = bindingResource.createBinding(binding);
    Response<CreateBindingResponse> response = call.execute();
    sharedPreferences.edit().putString(ENDPOINT + binding.identity, response.body().endpoint).commit();
  }
}

```

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 API.

```java title="Create a Binding (Client-side)"
public interface BindingResource {
    @POST("/register")
    Call<CreateBindingResponse> createBinding(@Body Binding binding);
}

```

The **Binding** class is a 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.

```java title="Create a Binding (Client-side)"
public class Binding {
    public String identity;
    public String endpoint;
    public String Address;
    public String BindingType;

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

```

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.

```java title="Create a Binding (Client-side)"
package com.twilio.notify.quickstart.notifyapi.model;

/**
 * Created by vmuller on 4/19/17.
 */
public class CreateBindingResponse {
    public String message;
    public String endpoint;

    public String getMessage() {
        return message;
    }

    public String getEndpoint() {
        return endpoint;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public void setEndpoint(String endpoint) {
        this.endpoint = endpoint;
    }
}

```

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 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**.

```xml title="Create a Binding (Client-side)"
<service android:name="[.MyInstanceIDService]" android:exported="false">
  <intent-filter>
         <action android:name="com.google.android.gms.iid.InstanceID"/>
  </intent-filter>
</service>
```

Then we can implement this 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

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.

| name        | description                                                                                                          |
| :---------- | :------------------------------------------------------------------------------------------------------------------- |
| Identity    | The Identity to which this Binding belongs. Identity is defined by your application and can have multiple endpoints. |
| Endpoint    | The identifier of the device to which this registration belongs. Endpoints are also defined by your application.     |
| BindingType | The type of the Binding determines the transport technology to use.                                                  |
| Address     | The address obtained from the vendor. For APNS it is the device token. For FCM, it is the registration token.        |

> \[!CAUTION]
>
> 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)

```js
// Download the helper library from https://www.twilio.com/docs/node/install
const twilio = require("twilio"); // Or, for ESM: import twilio from "twilio";

// Find your Account SID and Auth Token at twilio.com/console
// and set the environment variables. See http://twil.io/secure
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const client = twilio(accountSid, authToken);

async function createBinding() {
  const binding = await client.notify.v1
    .services("ISXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
    .bindings.create({
      address: "fcm_device_token",
      bindingType: "fcm",
      endpoint: "XXXXXXXXXXXXXXX",
      identity: "00000001",
      tag: ["preferred device"],
    });

  console.log(binding.sid);
}

createBinding();
```

```python
# Download the helper library from https://www.twilio.com/docs/python/install
import os
from twilio.rest import Client

# Find your Account SID and Auth Token at twilio.com/console
# and set the environment variables. See http://twil.io/secure
account_sid = os.environ["TWILIO_ACCOUNT_SID"]
auth_token = os.environ["TWILIO_AUTH_TOKEN"]
client = Client(account_sid, auth_token)

binding = client.notify.v1.services(
    "ISXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
).bindings.create(
    endpoint="XXXXXXXXXXXXXXX",
    tag=["preferred device"],
    identity="00000001",
    binding_type="fcm",
    address="fcm_device_token",
)

print(binding.sid)
```

```csharp
// Install the C# / .NET helper library from twilio.com/docs/csharp/install

using System;
using Twilio;
using Twilio.Rest.Notify.V1.Service;
using System.Threading.Tasks;
using System.Collections.Generic;

class Program {
    public static async Task Main(string[] args) {
        // Find your Account SID and Auth Token at twilio.com/console
        // and set the environment variables. See http://twil.io/secure
        string accountSid = Environment.GetEnvironmentVariable("TWILIO_ACCOUNT_SID");
        string authToken = Environment.GetEnvironmentVariable("TWILIO_AUTH_TOKEN");

        TwilioClient.Init(accountSid, authToken);

        var binding = await BindingResource.CreateAsync(
            endpoint: "XXXXXXXXXXXXXXX",
            tag: new List<string> { "preferred device" },
            identity: "00000001",
            bindingType: BindingResource.BindingTypeEnum.Fcm,
            address: "fcm_device_token",
            pathServiceSid: "ISXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");

        Console.WriteLine(binding.Sid);
    }
}
```

```java
// Install the Java helper library from twilio.com/docs/java/install

import java.util.Arrays;
import com.twilio.Twilio;
import com.twilio.rest.notify.v1.service.Binding;

public class Example {
    // Find your Account SID and Auth Token at twilio.com/console
    // and set the environment variables. See http://twil.io/secure
    public static final String ACCOUNT_SID = System.getenv("TWILIO_ACCOUNT_SID");
    public static final String AUTH_TOKEN = System.getenv("TWILIO_AUTH_TOKEN");

    public static void main(String[] args) {
        Twilio.init(ACCOUNT_SID, AUTH_TOKEN);
        Binding binding =
            Binding
                .creator("ISXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "00000001", Binding.BindingType.FCM, "fcm_device_token")
                .setEndpoint("XXXXXXXXXXXXXXX")
                .setTag(Arrays.asList("preferred device"))
                .create();

        System.out.println(binding.getSid());
    }
}
```

```go
// Download the helper library from https://www.twilio.com/docs/go/install
package main

import (
	"fmt"
	"github.com/twilio/twilio-go"
	notify "github.com/twilio/twilio-go/rest/notify/v1"
	"os"
)

func main() {
	// Find your Account SID and Auth Token at twilio.com/console
	// and set the environment variables. See http://twil.io/secure
	// Make sure TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN exists in your environment
	client := twilio.NewRestClient()

	params := &notify.CreateBindingParams{}
	params.SetEndpoint("XXXXXXXXXXXXXXX")
	params.SetTag([]string{
		"preferred device",
	})
	params.SetIdentity("00000001")
	params.SetBindingType("fcm")
	params.SetAddress("fcm_device_token")

	resp, err := client.NotifyV1.CreateBinding("ISXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
		params)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	} else {
		if resp.Sid != nil {
			fmt.Println(*resp.Sid)
		} else {
			fmt.Println(resp.Sid)
		}
	}
}
```

```php
<?php

// Update the path below to your autoload.php,
// see https://getcomposer.org/doc/01-basic-usage.md
require_once "/path/to/vendor/autoload.php";

use Twilio\Rest\Client;

// Find your Account SID and Auth Token at twilio.com/console
// and set the environment variables. See http://twil.io/secure
$sid = getenv("TWILIO_ACCOUNT_SID");
$token = getenv("TWILIO_AUTH_TOKEN");
$twilio = new Client($sid, $token);

$binding = $twilio->notify->v1
    ->services("ISXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
    ->bindings->create(
        "00000001", // Identity
        "fcm", // BindingType
        "fcm_device_token", // Address
        [
            "endpoint" => "XXXXXXXXXXXXXXX",
            "tag" => ["preferred device"],
        ]
    );

print $binding->sid;
```

```ruby
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'twilio-ruby'

# Find your Account SID and Auth Token at twilio.com/console
# and set the environment variables. See http://twil.io/secure
account_sid = ENV['TWILIO_ACCOUNT_SID']
auth_token = ENV['TWILIO_AUTH_TOKEN']
@client = Twilio::REST::Client.new(account_sid, auth_token)

binding = @client
          .notify
          .v1
          .services('ISXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
          .bindings
          .create(
            endpoint: 'XXXXXXXXXXXXXXX',
            tag: [
              'preferred device'
            ],
            identity: '00000001',
            binding_type: 'fcm',
            address: 'fcm_device_token'
          )

puts binding.sid
```

```bash
# Install the twilio-cli from https://twil.io/cli

twilio api:notify:v1:services:bindings:create \
   --service-sid ISXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX \
   --endpoint XXXXXXXXXXXXXXX \
   --tag "preferred device" \
   --identity 00000001 \
   --binding-type fcm \
   --address fcm_device_token
```

```bash
curl -X POST "https://notify.twilio.com/v1/Services/ISXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Bindings" \
--data-urlencode "Endpoint=XXXXXXXXXXXXXXX" \
--data-urlencode "Tag=preferred device" \
--data-urlencode "Identity=00000001" \
--data-urlencode "BindingType=fcm" \
--data-urlencode "Address=fcm_device_token" \
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN
```

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

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](/docs/notify/send-notifications) guide for more information.

[Next: Sending Notifications »](/docs/notify/send-notifications)
