> ## Documentation Index
> Fetch the complete documentation index at: https://v0.x-docs.novu.co/llms.txt
> Use this file to discover all available pages before exploring further.

# How to send push notifications in an Android app (react native) with FCM and Novu

> Learn how to send FCM push notifications in a React native Android app using Novu and FCM

## Prerequisites

To complete this tutorial, you will need the following:

* A [Firebase](https://firebase.google.com/) account
* A [Novu](https://web.novu.co/?utm_campaign=docs-gs-guides-fcm-android) account
* An [Expo](https://expo.dev) account

Push notifications are notifications that are sent to a user’s devices whether the user is using the app or not. We’ll be using the Firebase Cloud Messaging (FCM) integration of Novu to send these notifications. You can find the complete code for this project in our [Github repo.](https://github.com/novuhq/fcm-react-native-android)

## Start a React-Native project

We'll use the `create-expo` tool to initialize a new expo app. It creates a new React Native app with the expo package installed. We're naming our app `fcm-novu-rn2` and hence using the following command:

```javascript theme={null}
 npx create-expo-app fcm-novu-rn2
```

<Info>If it asks you to choose a template, choose the 'blank' template.</Info>

Now, go to the project directory and install the `react-native-firebase` package using the following command:

```bash theme={null}
npm install --save @react-native-firebase/app
```

Once this is installed, install the messaging module of Firebase using the following command:

```bash theme={null}
npm i --save @react-native-firebase/messaging
```

## Getting the FCM token

Now, we need to grab the `token key` from FCM. We'll need this to send notifications using FCM. We're using `useEffect` to grab this key as follows:

```jsx theme={null}
// import messaging module
import messaging from '@react-native-firebase/messaging';

// Request permission to send notifications
const authStatus = await messaging().requestPermission();

// Check if permission is granted or provisional
const enabled =
  authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
  authStatus === messaging.AuthorizationStatus.PROVISIONAL;

// If permission is granted or provisional, proceed
if (enabled) {
  // Log the authorization status
  console.log('Authorization status:', authStatus);

  // Retrieve the FCM token for the device
  const token = await messaging().getToken();
  // Log the FCM token
  console.log('FCM Token is:', token);

  // Return a function to unsubscribe from notifications
  return unsubscribe;
} else {
  // If permission is not granted, log the error status
  console.log('Could not grab token...', authStatus);
}

```

## FCM handlers

FCM uses something called a `background handler` to, as the name suggests handle notifications when the app is in the background. So, we'll add it to our app:

```jsx theme={null}
// Background message handler for incoming messages while the app is in bg
messaging().setBackgroundMessageHandler(async (remoteMessage) => {
  // Log a message indicating that a message was handled in the background
  console.log('Message handled in the background!', remoteMessage);
});

```

Similarly, we also need a `foreground handler` to handle notifications when the app is in the foreground. In our case, we're updating a state's value in our handler. Here's our foreground handler:

```jsx theme={null}
// handle incoming messages while the app is in the foreground
const unsubscribe = messaging().onMessage(async (remoteMessage) => {
  // Log a message indicating that the onMessage event is working
  console.log('working!!!!');
  
  // Update state with the received message
  setNotification(remoteMessage);
});
return unsubscribe;
```

## Setting up Expo

In order to load projects from Expo CLI, we need a dev client to be installed in our app. To install it, execute the following command from the root of the project directory:

```bash theme={null}
 npx expo install expo-dev-client
```

Once installed, log into your expo account using the following command:

```bash theme={null}
eas login
```

It'll ask for your username and password and log you in.

Now, we are ready to create our build of the app. Use the following command to create a development build of the app for the Android platform:

```bash theme={null}
eas build --profile development --platform android
```

<Info>If expo asks if you want to automatically create an EAS project for your app, choose yes. Do the same when it asks you if you want to generate a new keystore.</Info>
<Warning>Do not change the Android package name, even if EAS asks you to!</Warning>

## Setting up Firebase

1. Create a Firebase account if you don't already have one. Then, create a new project and all the relevant details.

<Frame caption="Create a new Firebase project">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-web-push/project.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=cd180042444bc23848d4d68ebb68f3d8" width="2642" height="1500" data-path="images/fcm-web-push/project.png" />
</Frame>

2. Once your project has been created, you'll be greeted with this welcome screen and asked to add Firebase to your app, so let's do that.

<Frame caption="Now, we need to add firebase to our app">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-novu-rna/greet.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=f8c7f5021b27dfa222b68c4cd383e803" width="2968" height="1722" data-path="images/fcm-novu-rna/greet.png" />
</Frame>

3. We'll choose the 'Android' option because we're creating an Android app.

<Frame caption="Choose the web option to connect to a web app">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-novu-rna/android.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=00e1dd0210d1cf97797f2d50cf7a4bcf" width="2966" height="1706" data-path="images/fcm-novu-rna/android.png" />
</Frame>

4. Find the package name from the `app.json` file of the project:

<Frame caption="Find the package name from the `app.json` file.">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-novu-rna/json.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=a397c84ee8134df0f31a00fb15088cf4" width="3012" height="1878" data-path="images/fcm-novu-rna/json.png" />
</Frame>

5. Add this package name to Firebase:

<Frame caption="Add package name to Firebase.">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-novu-rna/package.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=a1006820f76ec0e3732f60d99055c8d4" width="2990" height="1710" data-path="images/fcm-novu-rna/package.png" />
</Frame>

6. Now, we need to add `SHA1` keys from our project to the Firebase app. Run the following command to obtain `SHA1` key. We'll get two `SHA1` keys, one of which we'll add to Firebase right now and the other one, later on.

```bash theme={null}
eas credentials
```

<Info>If it asks you to, choose the 'Android' platform then 'Development' build then 'Keystore' then 'Set up a new keystore' then 'Select Build Credentials' and then 'Create a new build credential configuration'.</Info>

<Frame caption="Run the given command to obtain `SHA1` key.">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-novu-rna/keys.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=37a99e690d66f04eb0254c6365c99d48" width="2256" height="1112" data-path="images/fcm-novu-rna/keys.png" />
</Frame>

7. Now copy the `SHA1` key and add it to Firebase and register the app:

<Frame caption="Add the `SHA1` key to the Firebase app.">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-novu-rna/key.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=9d9736692e14e04b665360614f520d51" width="2996" height="1714" data-path="images/fcm-novu-rna/key.png" />
</Frame>

8. Click 'next' on all the other options and finally click 'continue to console' as follows:

<Frame caption="We'll add the second `SHA1` key now.">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-novu-rna/console.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=7d1cc80c9c340e7af6d0da8e506180e1" width="2996" height="1714" data-path="images/fcm-novu-rna/console.png" />
</Frame>

9. Go to 'project settings' and scroll all the way down

<Frame caption="Scroll till you see the `SHA1` key you added earlier.">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-novu-rna/settings.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=76523e556251e7aa4667dffb3830688c" width="2958" height="1710" data-path="images/fcm-novu-rna/settings.png" />
</Frame>

10. Click on the 'Add fingerprint' button and add the second `SHA1` key here.

<Frame caption="Add the second `SHA1` key.">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-novu-rna/fp.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=e12ba0317eecbf9bd5ce54b08e4d2695" width="2954" height="1716" data-path="images/fcm-novu-rna/fp.png" />
</Frame>

11. Now, download the Google services file and add it to the project's root directory. We also need to specify its location in the `app.json` file:

<Frame caption="Specify the location of Google services file in the `app.json` file.">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-novu-rna/location.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=31e014c01b81755b8b44ab752a7005be" width="3018" height="1886" data-path="images/fcm-novu-rna/location.png" />
</Frame>

12. Now we need to upload the Firebase server key to expo. Go to project settings and find it under the 'Cloud Messaging' tab.

<Frame caption="Find the server key in the project settings.">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-novu-rna/server.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=1a208ea7d789d54222ff96ac6edc5972" width="2962" height="1712" data-path="images/fcm-novu-rna/server.png" />
</Frame>

13. Now, upload that key to expo using the following command:

```bash theme={null}
expo push:android:upload --api-key <your server key here> 
```

14. Rebuild the app using the following command and we're good to go!

```bash theme={null}
eas build --profile development --platform android
```

15. If you have an Android device with you, simply scan and install the app. Otherwise, if you want to run it on an emulator, simply copy the link given alongside the QR code and open it on the emulator and then install the app.

16. Start the server to run the app, using the following command:

```bash theme={null}
npx expo start --dev-client
```

Again, you can either scan the QR code or copy and paste the link.

<Frame caption="Start the server to run the app.">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-novu-rna/qr.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=54b4247314f6b3961af32ce4503c6a48" width="3016" height="1884" data-path="images/fcm-novu-rna/qr.png" />
</Frame>

<Warning>Sometimes it doesn't fire up the emulator even when you have it installed. In that case, start the emulator manually and run the server again!</Warning>

## Setting up Novu

We'll need a workflow to trigger notifications to our user's devices. Follow the steps below to create one to ensure we are on the path to making FCM work as expected:

1. Head over to the [Integrations Store](https://web.novu.co/integrations?utm_campaign=docs-guides-fcm-android) on the Novu Web Dashboard and make sure that you've turned on the 'Firebase Cloud Messaging' integration.

<Frame caption="Turn on Firebase Cloud Messaging integration from the Novu Dashboard">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-web-push/novu-dashboard.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=c8303876e97b78018dbb69495883602f" width="2648" height="1514" data-path="images/fcm-web-push/novu-dashboard.png" />
</Frame>

<Info>If you're doing this for the first time, you'll need to get your service account key from the [Firebase Console](https://console.firebase.google.com/). Read more about it in our [FCM provider docs.](https://docs.novu.co/channels-and-providers/push/fcm)</Info>
2\. Now, we need to create a workflow that we'll trigger from our app to send notifications. Head over to [workflows in the Novu Web Dashboard](https://web.novu.co/workflows?utm_campaign=docs-guides-fcm-android) and click on the 'Add a workflow' button.

<Frame caption="Click on the 'Add a workflow' button to create workflows">
  <img src="https://mintcdn.com/novu-v2-docs/7qUtW5tEHh6q8UFR/images/fcm-web-push/workflows.png?fit=max&auto=format&n=7qUtW5tEHh6q8UFR&q=85&s=25be2431f9223b2c62de907e014be6f0" width="2638" height="1514" data-path="images/fcm-web-push/workflows.png" />
</Frame>

3. Choose the 'blank workflow' option from the dropdown menu.

<Frame caption="Click on the 'Add a workflow' button to create workflows">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-web-push/blank.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=2eac4d89ea51096c1995069cab0b786e" width="2632" height="1504" data-path="images/fcm-web-push/blank.png" />
</Frame>

3. Drag and drop the 'Push' node below the Workflow Trigger node.

<Frame caption="Drag and drop the 'Push' node below the Workflow Trigger node">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-web-push/drag.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=3139da69c413e78c19d902bc3701f580" width="2674" height="1518" data-path="images/fcm-web-push/drag.png" />
</Frame>

4. If you hover over the newly added 'Push' node, you'll see an error saying 'Message content and title are missing'.

<Frame caption="You'll get an error saying 'Message content and title are missing'">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-web-push/error.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=3d522021d48fbdbf81b32fb4b41065da" width="2662" height="1502" data-path="images/fcm-web-push/error.png" />
</Frame>

5. We're going to add a title and body for notifications. So, add them and give your workflow a suitable name.

<Frame caption="Add the identifiers that you'll use">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-novu-rna/title.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=eb030036190270b02fce4b550ffc0d70" width="2998" height="1712" data-path="images/fcm-novu-rna/title.png" />
</Frame>

6. Now, click on the 'Update' and then the 'get snippet' button to get the trigger code.

<Frame caption="Click on the 'get snippet' button to get the trigger code">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-novu-rna/snippet.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=29dcab21936735a0f0f539349477dc11" width="2992" height="1688" data-path="images/fcm-novu-rna/snippet.png" />
</Frame>

## Create a subscriber and update credentials

A subscriber is essentially the recipient of the notifications sent through Novu’s system. When you create a subscriber, you’re setting up the necessary information for Novu to send targeted notifications to. You can find more about subscribers in [our docs.](https://docs.novu.co/subscribers/subscribers)
To create a subscriber, we'll use the `identify` method:

```jsx theme={null}
// creating new instance of Novu
const novu = new Novu("<Novu API key>");

// creating subscriber
await novu.subscribers.identify('newSubForRNA', {
    firstName: "RNA"
});
```

Now, we'll add the FCM token that we'd received [earlier](#getting-the-fcm-token) to this subscriber using the `setCredentials` method:

```jsx theme={null}
await novu.subscribers.setCredentials('newSubForRNA', PushProviderIdEnum.FCM, {
    deviceTokens: ['<Enter the FCM token here>'],
});
// notice the use of 'newSubForRNA' here. This identifies the subscriber to which we're adding the FCM token
```

## Sending a push notification using Novu

To send a notification with Novu, we are actually triggering a notification workflow. Here's how to do it using Node:

```jsx theme={null}
novu.trigger('rna-2', {
    to: {
        subscriberId: 'newSubForRNA'
    },
    payload: {},
})
```

When triggered using the trigger code from above, this is the notification received on the device:

<Frame caption="A notification is successfully received on the device">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-novu-rna/hardcoded.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=9b70d8620025e0e44c393e7160e620e8" width="1080" height="2220" data-path="images/fcm-novu-rna/hardcoded.png" />
</Frame>

## Dynamic content

So far, we've sent notifications that have had "hard-coded" content. Now we'll send dynamic data when triggering a notification.

The way to do so is by changing the values of the title and the body to `{{title}}` and `{{body}}` in our workflow.

1. Go to the workflow we'd created earlier and change the values of the title and the body to `{{title}}` and `{{body}}` respectively.

<Frame caption="You can send dynamic content in notifications by changing the workflow.">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-novu-rna/custom.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=a48e210f4f85710622b7020c7d19c1ff" width="2996" height="1710" data-path="images/fcm-novu-rna/custom.png" />
</Frame>

2. Simply add these identifiers to the payload by changing the trigger code:

```jsx theme={null}
novu.trigger('rna-2', {
    to: {
        subscriberId: 'newSubForRNA'
    },
    payload: {
        title: payloadTitle,
        body: payloadBody
    },
});
```

<Note>We're extracting `payloadTitle` and `payloadBody` from the request body</Note>
Now, the notification delivered to the subscriber will contain dynamic data as shown below:

<Frame caption="A notification with dynamic content is successfully received on the device">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-novu-rna/dynamic.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=35168517af31e2d0529cc830cd076dc4" width="1080" height="2220" data-path="images/fcm-novu-rna/dynamic.png" />
</Frame>

## Sending images

Up to this point, your notifications have all contained only text. But if you’ve received many notifications, you know that notifications can have rich content, such as images. It’d be great if your notifications showed users a nice image related to their content. Once again, Firebase makes this super simple.

All you need to do is to specify the `URL` of the image in the override as shown below:

```jsx theme={null}
novu.trigger('rna-2', {
    to: {
        subscriberId: 'newSubForRNA'
    },
    payload: {
        title: payloadTitle,
        body: payloadBody
    },
    overrides: {
        fcm: {
            android: {
                notification: {
                    imageUrl: 'URL of the image',
                }
            }
        }
    }
});
```

The following notification is what gets delivered to the subscriber:

<Frame caption="A notification with image content is successfully received on the device">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-novu-rna/image.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=2ae5a7aa1c59a7431abf2dd9196c4c42" width="1080" height="2220" data-path="images/fcm-novu-rna/image.png" />
</Frame>

## Handling data type messages

With FCM, you can send `Notification` and `Data` messages. We have handled sending notification messages. Let’s handle data messages. Data type messages are useful when, in addition to the usual data, you want to send some custom data. Maybe whether a subscriber has purchased the pro plan of our product or not, maybe which tier of usage they have purchased etc. You can do this easily by modifying the override. Here's an example of sending the subscription status using the identifier `subStatus`:

```jsx theme={null}
novu.trigger('rna-2', {
    to: {
        subscriberId: 'newSubForRNA'
    },
    payload: {
        title: payloadTitle,
        body: payloadBody
    },
    overrides: {
        fcm: {
            android: {
                    data: {
                        subStatus: "true"
                    },
            }
        }
    }
});
```

On the user's device, you can extract this out and have it displayed like this:

<Frame caption="A notification with custom data content is successfully received on the device">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-novu-rna/cd.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=068a0298d611eec483fd789e9db10208" width="1080" height="2220" data-path="images/fcm-novu-rna/cd.png" />
</Frame>

## Priority of a notification

FCM tries to deliver high-priority messages immediately. The priority of a notification can also be altered by changing the overrides, as shown below:

```jsx theme={null}
novu.trigger('rna-2', {
    to: {
        subscriberId: 'newSubForRNA'
    },
    payload: {
        title: payloadTitle,
        body: payloadBody
    },
    overrides: {
        fcm: {
            android: {
                    data: {
                        subStatus: "true"
                    },
                    notification: {
                        priority: 'low'
                    }
            }
        }
    }
});
```

<Frame caption="A low priority notification is successfully received on the device">
  <img src="https://mintcdn.com/novu-v2-docs/vgBgpur1s6gL5HkB/images/fcm-novu-rna/priority.png?fit=max&auto=format&n=vgBgpur1s6gL5HkB&q=85&s=f33a49a0abd8a3a3f536f026fde6d0f4" width="1080" height="2220" data-path="images/fcm-novu-rna/priority.png" />
</Frame>

## Additional resources

* [Firebase Cloud Messaging](https://firebase.google.com/docs/cloud-messaging)
* [FCM Architectural Overview](https://firebase.google.com/docs/cloud-messaging/fcm-architecture)
