# Generate a device token for Android

> \[!IMPORTANT]
>
> The Push Notifications API is currently available as a
> Private Beta product. The information contained in this document is subject to change. You acknowledge
> and agree that your use of the Twilio Push Notifications API is subject to the terms of the [Services in
> Private Beta](https://www.twilio.com/en-us/legal/service-country-specific-terms/private-beta). This
> means that some features are not yet implemented and others may be changed before the product is
> declared as Generally Available. Private Beta products are not covered by the Twilio Support Terms or
> Twilio Service Level Agreement.

To send push notifications to Android devices with Twilio, your app needs a Firebase Cloud Messaging (FCM) registration token. This token uniquely identifies the app instance on a device. You then send this token to Twilio by including it in the `token` field when [sending a notification](/docs/push-notifications/api/notification-resource#send-a-pushnotification) or [registering a device](/docs/push-notifications/api/device-registration-resource#register-a-device).

## Prerequisites

* An Android project targeting Android 6.0 (API level 23) or higher.
* Firebase added to your Android project. Follow the [Add Firebase to your Android project](https://firebase.google.com/docs/android/setup) guide if you haven't already.

## Add the FCM dependency

Add the Firebase Cloud Messaging dependency to your module-level `build.gradle` file:

```groovy {title:"build.gradle"}
dependencies {
    implementation 'com.google.firebase:firebase-messaging'
}
```

## Request notification permission on Android 13+

Android 13 (API level 33) and higher require a runtime permission to display notifications. The FCM SDK includes the `POST_NOTIFICATIONS` permission in its manifest, but your app must also request it at runtime.

## Kotlin

```kotlin
private val requestPermissionLauncher = registerForActivityResult(
    ActivityResultContracts.RequestPermission(),
) { isGranted: Boolean ->
    if (isGranted) {
        // FCM SDK (and your app) can post notifications.
    } else {
        // Inform the user that notifications are disabled.
    }
}

private fun askNotificationPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
            PackageManager.PERMISSION_GRANTED
        ) {
            // Permission already granted.
        } else {
            requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
        }
    }
}
```

## Java

```java
private final ActivityResultLauncher<String> requestPermissionLauncher =
    registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
        if (isGranted) {
            // FCM SDK (and your app) can post notifications.
        } else {
            // Inform the user that notifications are disabled.
        }
    });

private void askNotificationPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
                PackageManager.PERMISSION_GRANTED) {
            // Permission already granted.
        } else {
            requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS);
        }
    }
}
```

## Retrieve the FCM registration token

Call `FirebaseMessaging.getInstance().getToken()` to retrieve the current registration token. This makes a network call on the first request and returns a cached token on subsequent calls.

## Kotlin

```kotlin
FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
    if (!task.isSuccessful) {
        Log.w(TAG, "Fetching FCM registration token failed", task.exception)
        return@addOnCompleteListener
    }

    val token = task.result
    // Send this token to Twilio using the DeviceRegistrations API
    // or include it directly in a PushNotifications request.
}
```

## Java

```java
FirebaseMessaging.getInstance().getToken()
    .addOnCompleteListener(task -> {
        if (!task.isSuccessful()) {
            Log.w(TAG, "Fetching FCM registration token failed", task.getException());
            return;
        }

        String token = task.getResult();
        // Send this token to Twilio using the DeviceRegistrations API
        // or include it directly in a PushNotifications request.
    });
```

## Handle token refresh

FCM tokens can rotate at any time. To ensure your app always has a valid token, extend `FirebaseMessagingService` and override `onNewToken`. Send the updated token to your server so Twilio can continue delivering notifications.

## Kotlin

```kotlin
class MyFirebaseMessagingService : FirebaseMessagingService() {
    override fun onNewToken(token: String) {
        // Send the updated token to your server.
        sendRegistrationToServer(token)
    }
}
```

## Java

```java
public class MyFirebaseMessagingService extends FirebaseMessagingService {
    @Override
    public void onNewToken(@NonNull String token) {
        // Send the updated token to your server.
        sendRegistrationToServer(token);
    }
}
```

Register the service in your `AndroidManifest.xml`:

```xml {title:"AndroidManifest.xml"}
<service
    android:name=".MyFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>
```

The token may change when:

* The app is restored on a new device.
* The user uninstalls and reinstalls the app.
* The user clears app data.

## Send the token to Twilio

After you retrieve the token, include it in Twilio Push Notifications API requests using `"provider": "FCM"`. You can either:

* **Send directly**: Include the token in the `to` array when [sending a notification](/docs/push-notifications/api/notification-resource#send-a-pushnotification).
* **Register the device**: Store the token as a [DeviceRegistration](/docs/push-notifications/api/device-registration-resource#register-a-device) so you can send to Users by `userId`.

## Next steps

* [Send a push notification](/docs/push-notifications/send-a-push) using the token.
* [Obtain FCM credentials](/docs/push-notifications/fcm-credentials) to upload to Twilio.
* Review the [Firebase Cloud Messaging Android setup guide](https://firebase.google.com/docs/cloud-messaging/android/client) for additional configuration options.
