# Register device token

Stream needs the device's push token to deliver call notifications. The token is registered against the currently connected user via the `StreamVideoClient` and is then used by the backend to address pushes.

This page covers the four device-management methods exposed by the video client — registering a device, registering a VoIP device, listing the registered devices, and removing one.

<admonition type="note">

To receive non-ringing push notifications, your app needs to register a device push token with Stream via `client.addDevice` — the FCM registration token on Android and the APNs device token on iOS. Registration is idempotent, so it's safe to call regardless of whether the [ringing setup](/video/docs/react-native/incoming-calls/ringing/) is also enabled.

Note that the iOS VoIP token registered automatically as part of the ringing flow doesn't apply here — VoIP tokens are PushKit-only, so a separate APNs device token must be registered via `addDevice` for non-ringing notifications.

</admonition>

<admonition type="info">

Each user has a limit of **25 devices**. When the limit is reached, the oldest device is automatically removed and replaced by the newly registered one.

</admonition>

## Register a device

Use `client.addDevice()` to register a non-VoIP push token (FCM on Android, APNs on iOS).

```ts
await client.addDevice(
  device_token, // device push token
  push_provider, // e.g. "firebase" | "apn"
  push_provider_name, // optional — provider name from the Stream Dashboard
);
```

Typical usage, after obtaining the token from your push library:

```ts
// Android — FCM token
await client.addDevice(fcmToken, "firebase", "your-fcm-provider-name");

// iOS — APNs token (non-VoIP, used for non-ringing notifications)
await client.addDevice(apnToken, "apn", "your-apn-provider-name");
```

Subsequent calls with the same `id` are idempotent — the backend upserts the device, so you can safely call `addDevice` on every app launch or token refresh.

A registered device on Stream has the following params:

| Field                | Type       | Description                                                                                                                                                                               |
| -------------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                 | `string`   | The push token returned by the OS (FCM registration token, APNs device token, etc.).                                                                                                      |
| `push_provider`      | `string`   | E.g. `firebase`, `apn`                                                                                                                                                                    |
| `push_provider_name` | `string?`  | The provider name configured on the [Stream Dashboard](https://dashboard.getstream.io/). Required when you have multiple providers of the same type (e.g. separate dev / staging / prod). |
| `userID`             | `string?`  | The user the device belongs to. Defaults to the currently connected user — only set this on serverside requests.                                                                          |
| `voip_token`         | `boolean?` | `true` when the token is an iOS VoIP token used for the ringing flow. Not needed for non-ringing notifications.                                                                           |

## List devices

Use `client.getDevices()` to inspect which devices are currently registered for the connected user. This is the easiest way to verify a token actually made it to Stream.

```ts
const { devices } = await client.getDevices();

devices.forEach((device) => {
  console.log(
    device.id,
    device.user_id,
    device.push_provider,
    device.push_provider_name,
    device.disabled,
  );
});
```

Pass a `userID` only on serverside — it lets server tokens query devices for any user:

```ts
const { devices } = await client.getDevices("user-id");
```

## Unregister a device

Call `client.removeDevice()` to remove a device, typically on logout, so Stream stops sending pushes to that token.

```ts
await client.removeDevice(deviceToken);

// Serverside only — remove a device for a specific user
await client.removeDevice(deviceToken, "user-id");
```

<admonition type="note">

If you use the ringing setup and your only goal is to clean up tokens registered by the SDK on logout, prefer `StreamVideoRN.onPushLogout()` — it removes both the FCM and VoIP tokens that the SDK registered. For tokens you registered yourself (e.g. the non-ringing APNs token), you still need to call `removeDevice` directly.

</admonition>


---

This page was last updated at 2026-05-25T15:27:30.927Z.

For the most recent version of this documentation, visit [https://getstream.io/video/docs/react-native/incoming-calls/non-ringing-notifications-setup/register-device/](https://getstream.io/video/docs/react-native/incoming-calls/non-ringing-notifications-setup/register-device/).