Bird
Raised Fist0
React Nativemobile~20 mins

Push notifications with FCM in React Native - Mini App: Build & Ship

Choose your learning style10 modes available
Build: Push Notification Demo
This screen registers the app for Firebase Cloud Messaging (FCM) push notifications and displays the latest notification message received.
Target UI
-------------------------
| Push Notification Demo |
-------------------------
|                       |
| Latest message:       |
|                       |
| [No messages yet]     |
|                       |
|-----------------------|
| [Request Permission]  |
|-----------------------|
Request user permission for push notifications
Register device with FCM to receive push tokens
Listen for incoming push notifications while app is in foreground
Display the latest notification message on screen
Add a button to manually request notification permission
Starter Code
React Native
import React, { useState, useEffect } from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
import messaging from '@react-native-firebase/messaging';

export default function PushNotificationDemo() {
  const [message, setMessage] = useState('No messages yet');

  useEffect(() => {
    // TODO: Request permission and listen for messages
  }, []);

  const requestPermission = async () => {
    // TODO: Request notification permission
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Push Notification Demo</Text>
      <Text style={styles.label}>Latest message:</Text>
      <Text style={styles.message}>{message}</Text>
      <Button title="Request Permission" onPress={requestPermission} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20 },
  title: { fontSize: 24, marginBottom: 20 },
  label: { fontSize: 18, marginBottom: 10 },
  message: { fontSize: 16, marginBottom: 30, fontStyle: 'italic' }
});
Task 1
Task 2
Task 3
Solution
React Native
import React, { useState, useEffect } from 'react';
import { View, Text, Button, StyleSheet, Alert } from 'react-native';
import messaging from '@react-native-firebase/messaging';

export default function PushNotificationDemo() {
  const [message, setMessage] = useState('No messages yet');

  useEffect(() => {
    async function setupFCM() {
      const authStatus = await messaging().requestPermission();
      const enabled = authStatus === messaging.AuthorizationStatus.AUTHORIZED || authStatus === messaging.AuthorizationStatus.PROVISIONAL;

      if (enabled) {
        const token = await messaging().getToken();
        console.log('FCM Token:', token);
      } else {
        Alert.alert('Permission denied', 'Push notifications permission was not granted');
      }
    }

    setupFCM();

    const unsubscribe = messaging().onMessage(async remoteMessage => {
      if (remoteMessage.notification) {
        setMessage(remoteMessage.notification.title + ': ' + remoteMessage.notification.body);
      }
    });

    return unsubscribe;
  }, []);

  const requestPermission = async () => {
    try {
      const authStatus = await messaging().requestPermission();
      if (authStatus === messaging.AuthorizationStatus.AUTHORIZED || authStatus === messaging.AuthorizationStatus.PROVISIONAL) {
        Alert.alert('Permission granted', 'You will receive push notifications');
      } else {
        Alert.alert('Permission denied', 'Push notifications permission was not granted');
      }
    } catch (error) {
      Alert.alert('Error', 'Failed to request permission');
    }
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Push Notification Demo</Text>
      <Text style={styles.label}>Latest message:</Text>
      <Text style={styles.message}>{message}</Text>
      <Button title="Request Permission" onPress={requestPermission} accessibilityLabel="Request push notification permission button" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20 },
  title: { fontSize: 24, marginBottom: 20 },
  label: { fontSize: 18, marginBottom: 10 },
  message: { fontSize: 16, marginBottom: 30, fontStyle: 'italic' }
});

This app uses the @react-native-firebase/messaging library to handle push notifications with Firebase Cloud Messaging (FCM). In the useEffect hook, it requests notification permission from the user and obtains the FCM token if permission is granted. It also sets up a listener with messaging().onMessage to receive notifications when the app is in the foreground and updates the displayed message accordingly.

The Request Permission button allows the user to manually request notification permission again if needed. Alerts inform the user about permission status. The UI shows the latest notification message or a placeholder if none received yet.

This simple setup helps beginners understand how to integrate push notifications in React Native apps using FCM.

Final Result
Completed Screen
-------------------------
| Push Notification Demo |
-------------------------
|                       |
| Latest message:       |
|                       |
| New Offer: 50% off!   |
|                       |
|-----------------------|
| [Request Permission]  |
|-----------------------|
When the app starts, it asks for notification permission automatically.
If a push notification arrives while the app is open, the message text updates to show the notification title and body.
Tapping the 'Request Permission' button asks the user for notification permission again.
Alerts show whether permission was granted or denied.
Stretch Goal
Add a feature to display the FCM token on screen after permission is granted.
💡 Hint
Store the token in a state variable and show it below the latest message text.

Practice

(1/5)
1. What is the main purpose of Firebase Cloud Messaging (FCM) in a React Native app?
easy
A. To create UI components
B. To store user data locally
C. To send push notifications to the app users
D. To manage app navigation

Solution

  1. Step 1: Understand FCM's role

    FCM is a service designed to send push notifications to apps.
  2. Step 2: Compare options

    Only To send push notifications to the app users describes sending push notifications, which is FCM's main purpose.
  3. Final Answer:

    To send push notifications to the app users -> Option C
  4. Quick Check:

    FCM = Push notifications [OK]
Hint: FCM is about messaging, not UI or storage [OK]
Common Mistakes:
  • Confusing FCM with local data storage
  • Thinking FCM manages UI or navigation
  • Assuming FCM is for database operations
2. Which React Native Firebase method is used to get the device token for FCM push notifications?
easy
A. messaging().requestPermission()
B. messaging().getToken()
C. messaging().sendMessage()
D. messaging().subscribeToTopic()

Solution

  1. Step 1: Identify token retrieval method

    The method to get the device token is messaging().getToken().
  2. Step 2: Eliminate other options

    requestPermission() asks user permission, sendMessage() sends messages, subscribeToTopic() subscribes to topics.
  3. Final Answer:

    messaging().getToken() -> Option B
  4. Quick Check:

    Get token = getToken() [OK]
Hint: Get token with getToken(), not requestPermission() [OK]
Common Mistakes:
  • Using requestPermission() to get token
  • Confusing sendMessage() with token retrieval
  • Mixing subscribeToTopic() with token methods
3. What will be the output of this code snippet in a React Native app using FCM?
import messaging from '@react-native-firebase/messaging';

async function getToken() {
  const token = await messaging().getToken();
  console.log(token);
}

getToken();
medium
A. Logs the device's FCM token string to the console
B. Throws a syntax error due to missing await
C. Logs 'undefined' because getToken() returns nothing
D. Throws a runtime error because messaging() is undefined

Solution

  1. Step 1: Analyze async function behavior

    The function awaits messaging().getToken(), which returns the device token string.
  2. Step 2: Understand console.log output

    It logs the token string, not undefined or error, assuming messaging is imported correctly.
  3. Final Answer:

    Logs the device's FCM token string to the console -> Option A
  4. Quick Check:

    getToken() returns token string [OK]
Hint: Await getToken() to get token string, then log it [OK]
Common Mistakes:
  • Forgetting await causing Promise logged
  • Assuming getToken() returns undefined
  • Not importing messaging correctly
4. You wrote this code to request permission for notifications but it doesn't work as expected:
import messaging from '@react-native-firebase/messaging';

messaging().requestPermission();
What is the likely problem?
medium
A. requestPermission() is not a valid method
B. You need to import notifications instead of messaging
C. You must call getToken() before requestPermission()
D. You forgot to await the requestPermission() call

Solution

  1. Step 1: Check async method usage

    requestPermission() returns a Promise and should be awaited to complete permission request.
  2. Step 2: Identify missing await effect

    Without await, the permission request may not finish before next steps, causing unexpected behavior.
  3. Final Answer:

    You forgot to await the requestPermission() call -> Option D
  4. Quick Check:

    Await async calls like requestPermission() [OK]
Hint: Always await async permission requests [OK]
Common Mistakes:
  • Not awaiting async permission calls
  • Thinking requestPermission() is invalid
  • Calling getToken() before permission
5. You want to send a push notification only if the user has granted permission. Which code snippet correctly checks permission and then gets the FCM token in React Native?
hard
A. const authStatus = await messaging().requestPermission(); if (authStatus === messaging.AuthorizationStatus.AUTHORIZED) { const token = await messaging().getToken(); console.log(token); }
B. const token = await messaging().getToken(); if (token) { await messaging().requestPermission(); console.log(token); }
C. await messaging().getToken(); await messaging().requestPermission(); console.log('Permission and token done');
D. messaging().requestPermission(); messaging().getToken(); console.log('Permissions requested and token fetched');

Solution

  1. Step 1: Check permission before token

    const authStatus = await messaging().requestPermission(); if (authStatus === messaging.AuthorizationStatus.AUTHORIZED) { const token = await messaging().getToken(); console.log(token); } requests permission and checks if authorized before getting token.
  2. Step 2: Verify async and order correctness

    const authStatus = await messaging().requestPermission(); if (authStatus === messaging.AuthorizationStatus.AUTHORIZED) { const token = await messaging().getToken(); console.log(token); } awaits both calls and uses correct AuthorizationStatus check.
  3. Final Answer:

    const authStatus = await messaging().requestPermission(); if (authStatus === messaging.AuthorizationStatus.AUTHORIZED) { const token = await messaging().getToken(); console.log(token); } -> Option A
  4. Quick Check:

    Check permission first, then get token [OK]
Hint: Request permission first, then get token if authorized [OK]
Common Mistakes:
  • Getting token before permission
  • Not awaiting async calls
  • Ignoring authorization status check
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard