# Push providers

A push provider is a configuration of a push API with one of four types: APN, Firebase, Huawei and Xiaomi. Chat supports all four provider types. Activity Feeds supports Firebase and APN.

Multiple providers can be added to the same Stream application to support:

- Different builds of the same application, such as prod and staging or regular and admin
- Different target platforms, such as starting with React Native and adapting native Android and iOS SDKs along the way
- Multi-tenant applications, where different customers need different configurations

While Stream doesn't have first class integration for push providers besides Firebase, APN, Huawei and Xiaomi, it is entirely possible to integrate with additional providers using [webhooks](https://getstream.io/docs/platform/webhooks/).

<Admonition type="info">

Management of push providers with the endpoints below only works if your app is upgraded to v2 or v3. Otherwise, the update app settings endpoint must be used for a single provider config per type (APN, Firebase, Huawei, Xiaomi).

</Admonition>

## Dashboard Configuration

1. Navigate to your Stream Dashboard
2. Select your application
3. Go to the **Push Notifications** section
4. Click **New Configuration** and select your provider
5. Upload your credentials

![Push Notifications Dashboard Menu](https://getstream.io/docs-assets/images/1e01c2d2e002.png)

**Firebase** requires a service account key from your FCM project:

**Firebase console → project settings (top left) → service accounts (4th sub header) → generate a new private key**

Export your key and upload it in the Firebase credentials field. A sample service account JSON:

<Tabs>

```json label="JSON"
{
  "type": "service_account",
  "project_id": "your-project-id",
  "private_key_id": "key-id",
  "private_key": "-----BEGIN PRIVATE KEY-----\nYOUR_PRIVATE_KEY\n-----END PRIVATE KEY-----\n",
  "client_email": "firebase-adminsdk-xxxxx@your-project.iam.gserviceaccount.com",
  "client_id": "client-id",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token"
}
```

</Tabs>

**APN** requires an Apple Developer account and an authentication key or certificate:

| Field Name             | Description                             |
| ---------------------- | --------------------------------------- |
| **Name**               | Descriptive name for this configuration |
| **Bundle ID**          | Your iOS app's bundle identifier        |
| **Team ID**            | Your Apple Developer Team ID            |
| **Key ID**             | Your APNs authentication key ID         |
| **Authentication Key** | Your .p8 private key file               |

## Upsert a Push Provider

In the same endpoint, a new config can be created or updated.

<Admonition type="warning">

Up to 25 push providers can be added to a single application.

</Admonition>

<Admonition type="info">

If the authentication information is updated, linked devices might be invalidated in the next push message sent retry.

</Admonition>

<Tabs>

```js label="JavaScript"
const pushProviderConfig = {
  name: "my-custom-name",
  type: "firebase",
  firebase_credentials: "my-service-account-information",
};

client.upsertPushProvider(pushProviderConfig);
```

```ruby label="Ruby"
require 'getstream_ruby'
Models = GetStream::Generated::Models

client.common.upsert_push_provider(Models::UpsertPushProviderRequest.new(
  push_provider: Models::PushProvider.new(
    name: 'my-custom-name',
    type: 'firebase',
    firebase_credentials: 'my-service-account-information'
  )
))
```

```go label="Go"
client.UpsertPushProvider(ctx, &getstream.UpsertPushProviderRequest{
  PushProvider: &getstream.PushProviderRequest{
    Name:                "my-custom-name",
    Type:                getstream.PtrTo("firebase"),
    FirebaseCredentials: getstream.PtrTo("my-service-account-information"),
  },
})
```

</Tabs>

## List Push Providers

<Tabs>

```js label="JavaScript"
client.listPushProviders();
```

```ruby label="Ruby"
require 'getstream_ruby'

client.common.list_push_providers
```

```go label="Go"
client.ListPushProviders(ctx, &getstream.ListPushProvidersRequest{})
```

</Tabs>

## Delete a Push Provider

<Tabs>

```js label="JavaScript"
const pushProviderID = {
  type: "apn or firebase or huawei or xiaomi",
  name: "your given custom name while creating",
};

client.deletePushProvider(pushProviderID);
```

```ruby label="Ruby"
require 'getstream_ruby'

provider_type = 'apn or firebase or huawei or xiaomi'
provider_name = 'your given custom name while creating'

client.common.delete_push_provider(provider_type, provider_name)
```

```go label="Go"
pushProviderType := "apn or firebase or huawei or xiaomi"
pushProviderName := "your given custom name while creating"

client.DeletePushProvider(ctx, pushProviderType, pushProviderName, &getstream.DeletePushProviderRequest{})
```

</Tabs>

## Linking Devices to Providers

By default, adding a device doesn't require a push provider linking due to backward compatibility where old configurations don't have a `name`, so their names are empty.

- If the configuration name is not provided when adding a device, devices will be matched with configurations according to only their types.

- If the configuration name is provided, but invalid, the request will fail with a bad request error.

When devices are added, they can be linked to a provider to inherit their configuration.

<Tabs>

```js label="JavaScript"
const pushToken = "your client side generated device token to receive pushes";
const pushProviderType = "apn or firebase or huawei or xiaomi";
const userId = "your user id for server side calls";
const pushProviderName =
  "the name of the provider you created while configuring your app";

client.addDevice(pushToken, pushProviderType, userId, pushProviderName);
```

```go label="Go"
client.CreateDevice(ctx, &getstream.CreateDeviceRequest{
  ID:               "your client side generated device token to receive pushes",
  UserID:           getstream.PtrTo("your user id for server side calls"),
  PushProvider:     "apn or firebase or huawei or xiaomi",
  PushProviderName: getstream.PtrTo("the name of the provider you created while configuring your app"),
})
```

</Tabs>

## Single-Provider Configuration

If you're not interested in multi-bundle support, you can leverage the `updateAppSettings` endpoint to add push configuration for a single APN, Firebase, Huawei or Xiaomi provider.

<Tabs>

```js label="JavaScript"
// this configuration is same with upsert push provider
// except type is inherent and naming is missing so it's set to empty string
const firebase_config = {
  credentials_json: "my-service-account-information",
};

client.updateAppSettings({ firebase_config });
```

```go label="Go"
// this configuration is same with upsert push provider
// except type is inherent and naming is missing so it's set to empty string
client.UpdateApp(ctx, &getstream.UpdateAppRequest{
  FirebaseConfig: &getstream.FirebaseConfig{
    CredentialsJson: getstream.PtrTo("my-service-account-information"),
  },
})
```

</Tabs>

## Selecting a Configuration in the Feeds Client SDKs

When initializing the Activity Feeds SDK, specify which configuration to use:

```swift
let notificationsConfig = PushNotificationsConfig(
    pushProviderInfo: PushProviderInfo(
        name: "production-ios", // The name you gave in the dashboard
        pushProvider: .apn
    )
)

let config = FeedsConfig(pushNotificationsConfig: notificationsConfig)
```


---

This page was last updated at 2026-08-10T16:01:01.267Z.

For the most recent version of this documentation, visit [https://getstream.io/docs/platform/push-providers/](https://getstream.io/docs/platform/push-providers/).