Push notifications improve engagement with your app. Firebase provides a way to send them using their Firebase Cloud Messaging service. I'm going to show you how to integrate it in your React app.
What we are building
Get the complete code here.
Create Firebase project
- Add project from the Firebase Console
- Add a Web App to your firebase project
- Press
Continue to console
Add firebase to React app
- Install Firebase CLI
npm i -g firebase-tools
- Clone React app tutorial starter
npx degit https://github.com/jeremytenjo/starter-demo.git firebase-messaging-with-react && cd firebase-messaging-with-react && npm i && npm run dev
- Install dependencies
npm i firebase @useweb/use-firebase-messaging @useweb/use-firebase
- Setup firebase in app
firebase init hosting
- Click
Use an existing project - Click
tut-push-notifications (tut-push-notifications) - Select the following options:
? What do you want to use as your public directory? public
? Configure as a single-page app (rewrite all urls to /index.html)? Yes
? Set up automatic builds and deploys with GitHub? No
Firebase initialized 🎉
Firebase will create
firebase.jsonand.firebaserc
- Add
gcm_sender_idproperty tomanifest.json. Insert the value below AS IT IS, without changing.
{
"gcm_sender_id": "103953800507"
}
- Create a firebase-messaging-sw.js file in your public folder. This service worker will receive and display notification when your app is in the background.
/* eslint-disable no-undef */
importScripts('https://www.gstatic.com/firebasejs/8.6.8/firebase-app.js')
importScripts('https://www.gstatic.com/firebasejs/8.6.8/firebase-messaging.js')
const firebaseConfig = undefined // firebaseConfig is required
firebase.initializeApp(firebaseConfig)
const messaging = firebase.messaging()
messaging.onBackgroundMessage((payload) => {
console.log('[firebase-messaging-sw.js] Received background message ', payload)
const notificationTitle = payload.notification.title
const notificationOptions = {
body: payload.notification.body,
icon: payload.notification.icon || payload.notification.image,
}
self.registration.showNotification(notificationTitle, notificationOptions)
})
self.addEventListener('notificationclick', (event) => {
if (event.action) {
clients.openWindow(event.action)
}
event.notification.close()
})
- Replace
firebaseConfig = undefinedinfirebase-messaging-sw.jswith your firebase config. Find underProject settingsin the firebase console.
- Create
src/services/Firebase/Firebase.tsxand add the following code. We are using the@useweb/use-firebasepackage in order to pass necessary data to the@useweb/use-firebase-messagingpackage we will use later on.
import React from 'react'
import { FirebaseProvider } from '@useweb/use-firebase'
import { initializeApp } from 'firebase/app'
import { getMessaging } from 'firebase/messaging'
const firebaseConfig = undefined // firebaseConfig is required
const firebaseApp = initializeApp(firebaseConfig)
const messaging = getMessaging(firebaseApp)
const envIsDev = process.env.NODE_ENV === 'development'
const vapidKey = undefined // vapidKey is required
export default function Firebase({ children }) {
return (
<FirebaseProvider
firebaseConfig={firebaseConfig}
firebaseApp={firebaseApp}
envIsDev={envIsDev}
messaging={messaging}
messagingOptions={{
vapidKey,
}}
>
{children}
</FirebaseProvider>
)
}
- Replace
firebaseConfig = undefinedinsrc/services/Firebase/Firebase.tsxwith your firebase config. Find underProject settingsin the firebase console.
- Generate firebase messaging
vapidKey
- Open the Cloud Messaging tab in the Firebase console Project Settings and scroll to the Web configuration section.
- In the
Web Push certificatestab, click theGenerate key pairbutton.
Replace
vapidKey = undefinedinsrc/services/Firebase/Firebase.tsxwith your generatedvapidKeyWrap you app with
Firebase.tsx
src/index.tsx
import React from 'react'
import ReactDOM from 'react-dom'
import Firebase from './services/firebase/firebase'
import Router from './pages/router'
import Theme from './theme/theme'
function App() {
return (
<Firebase>
<Theme>
<Router />
</Theme>
</Firebase>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
- We are going to use
@useweb/use-firebase-messagingto retrieve our FCM registration token and handle notifications while the app is in the foreground. Add the following code topages/HomePage/HomePage.tsx
import React, { useEffect } from 'react'
import Box from '@mui/material/Box'
import Button from '@mui/material/Button'
import LinearProgress from '@mui/material/LinearProgress'
import useFirebaseMessaging from '@useweb/use-firebase-messaging'
import CopyToClipboard from '../../lib/components/CopyToClipboard/CopyToClipboard'
import Text from '../../lib/components/Text/Text'
import Header from '../../lib/components/_unique/Header/Header'
import useSnackbar from '../../lib/components/Snackbar/Snackbar'
export default function HomePage() {
const snackbar = useSnackbar()
const firebaseMessaging = useFirebaseMessaging({
onMessage: (message) => {
console.log(`Received foreground message`, message)
snackbar.show({
message: message?.notification?.title || message?.data?.title,
})
},
})
useEffect(() => {
firebaseMessaging.init()
}, [])
return (
<Box>
<Header
title='Firebase Messaging Push Notification Example'
tutorialLink='how-to-send-push-notifications-with-firebase-and-react'
repoLink='https://github.com/jeremytenjo/how-to-send-push-notifications-with-firebase-and-react'
/>
{firebaseMessaging.initializing && (
<>
<Text
text='Initializing Firebase Messaging (enable notifications for this page)'
sx={{ mb: 2 }}
/>
<LinearProgress />
</>
)}
{firebaseMessaging.error && (
<Text text={firebaseMessaging.error.toString()} sx={{ color: 'red' }} />
)}
{firebaseMessaging.fcmRegistrationToken && (
<>
<Box
sx={{
display: 'grid',
gridAutoFlow: 'column',
justifyContent: 'start',
alignItems: 'center',
mb: 1,
gridGap: '10px',
}}
>
<Text text='FCM Registration Token:' />
<CopyToClipboard text={firebaseMessaging.fcmRegistrationToken}>
<Button>Copy</Button>
</CopyToClipboard>
</Box>
<Text
text={firebaseMessaging.fcmRegistrationToken}
sx={{
width: '100%',
overflowWrap: 'break-word',
fontSize: '14px',
color: 'grey.main',
}}
/>
</>
)}
</Box>
)
}
That is it, now lets test push notifications using the generated FCM registration token
Open
http://localhost:3001/Open Firebase message composer
Click on
New campaignbuttonClick on
Notificationsbutton
Add
Notification titleandNotification textClick
Send test messageAdd the registration token generated from
http://localhost:3001/and click the plus iconClick
Test
🎉 Your app will show a snackbar if the app is in the foreground or it will show the native notification if the app is in the background
Send notification from a cloud function (Advanced)
- Get
FCM registration tokento send cloud messages to.
const messaging = useFirebaseMessaging({
onFcmRegistrationToken: (fcmRegistrationToken) => {
console.log(fcmRegistrationToken)
},
})
- Send message from nodejs function/app
const message = {
data: {
title: `New episodes aired recently!`,
image: `/images/logo/assets/logo.png`,
icon: `/images/logo/assets/logo.png`,
body,
actions: JSON.stringify(actions),
},
tokens: fcmRegistrationToken,
}
functions.logger.info('FCM Message', message)
// https://firebase.google.com/docs/cloud-messaging/send-message#send-messages-to-multiple-devices
const response = await messaging.sendMulticast(message)
That's all for now. I hope you find this tutorial helpful! Feel free to leave feedback or questions below, I would love to hear and work on them.
For more content, follow me on Twitter ✌️










Top comments (2)
I'm having trouble with background notifications, when I click on them nothing happens, would my App.js file be able to see when it was clicked?
Hi @danielfoga
Use
self.addEventListener('notificationclick', (event) => {}to listen to background notification clicks.For example:
firebase-messaging-sw.js