Real-time Chat Blog

How to Add a Notification Badge to Icons in React Native

6 min read Michael Carroll on Dec 19, 2022
Try PubNub Today

Free up to 1MM monthly messages. No credit card required.

Subscribe to our newsletter

By submitting this form, you are agreeing to our Terms and Conditions and Privacy Policy.

Display real-time notification badges with PubNub and React Native to display important information and bring users back to your application.

What are icon badges?

Icon badges, or notification badges, are useful UI elements in any Android or iOS application. They allow icons to become alive and indicate that there is important data for users to view in real time. They might show how many users are online, a notification count, new updates and news, or the number of unread messages. You've seen icon and notification badges in applications such as Facebook, Snapchat, Instagram, and YouTube.Although you can create notification badges locally within applications, these will not update in real time. Luckily, with PubNub, building real-time notification badges are simple.

In this tutorial, you will be using React Native libraries to clone Facebook Messenger and add badges to the icons. PubNub will be used to power the real-time updates to the badge. The final result will be a simple application that looks as follow.

Final App Image

Although this application will take you step-by-step through building a React Native application with an icon that will have a notification badge that updates in real time, you can find the final application's source code in the GitHub repository.

Environment Set up

In this section, you will install the necessary tools and dependencies to be able to simulate, run, and test the React Native app.

PubNub Account

You'll need to create a free PubNub account, as you'll need your publish/subscribe keys to send information across the PubNub Network. You can learn how to create your keys in this video/written walkthrough.

Ensure that you enable Presence to know when users come online and Message Persistence to persist information.

Development Environments

You will need to download and use your favorite code editor when developing this application. Visual Studio Code is recommended as it is a lightweight, open-source, and free code editor that supports different languages and frameworks. You should also add the React Native Tools plugin for debugging and integrated commands for React Native.

The next set of tools you’ll need for developing cross-platform applications is to download iOS and Android development environments. For iOS devices, you'll need to download Xcode. For Mac users, you can simply download Xcode for free in the app store. For PC users, you will need to simulate Mac OS with a Virtual Machine if you want to develop your app for iPhone. You can see how to do this here. For simulating Android applications, you'll need to download Android Studio.

Packages and Libraries

Download Node.js, the JavaScript runtime environment, as it is necessary to run React Native applications, as well as install packages with npm (which is included with the download).

Next, you'll install React Native. This is an open-source platform developed by Facebook that has become very popular over the years. React Native allows developers to write their applications in one language across multiple platforms, which allows you to develop for Android and iOS devices.

To set up the React Native development environment, you'll be using the React Native CLI, which will allow you to quickly install libraries, link packages, and simulate the app.

Navigate in the terminal/console to the folder you would like to develop this application. Use npm to install the React Native CLI command line utility.

sudo npm install -g react-native-cli
sudo npm install -g react-native

Note: You will be prompted to install CocoaPods after this installation. Say yes to this download and make sure you don’t run CocoaPods as root (i.e. make sure you installed react-native first using sudo and then you can use react-native as a normal user. CocoaPods then should run properly).

Then run the following commands to create a new React Native project called realtimebadge.

react-native init realtimebadge && cd realtimebadge

Install the following React Native libraries that will be used in your project, including the PubNub React SDK: React Native Elements, React Native Vector Icons, React Navigation, React Native Gesture Handler, and React PubNub to your project.

npm install --save react-native-elements react-native-vector-icons react-pubnub react-native-gesture-handler react-navigation && react-native link

Build and Run

Now it’s time to finally start building the React Native sample application with real-time updates for the badge notifications.

Building the UI

In your project directory, create a new folder in the root directory called src. Within src, create three more folders called navigationstyles, and screens.

Next, open App.js. Include the necessary React Native libraries including PubNub into your app and initialize a PubNub instance with the publish and subscribe keys you received earlier.

Under componentDidMount(), subscribe to an arbitrary channel, such as "channel1", with the boolean flag withPresence set to true.

import React, { Component } from "react";
import { Text } from "react-native";
import PubNubReact from 'pubnub-react';

export default class App extends Component {
  constructor(props) {
    super(props);
    this.pubnub = new PubNubReact({
    publishKey: "INSERT-PUB-KEY-HERE",
    subscribeKey: "INSERT-SUB-KEY-HERE"
    });
    this.state = {
    };

    this.pubnub.init(this);
  }

  componentDidMount() {
    this.pubnub.subscribe({
      channels: ['channel1'],
      withPresence: true
    });
  }

  render() {
    return <Text>Hello world.</Text>;
  }
}

After importing the libraries and initializing the constructor, create a blank screen as a default screen for each navigation view. You may modify this screen for your use cases, but in this tutorial, it will simply display “Empty screen.” as the text. Create the file Empty.js inside src/screens and place the following code inside Empty.js.

import React from "react";
import { StatusBar, StyleSheet, Text } from "react-native";
import { SafeAreaView } from "react-navigation";
import AppStyles from '../styles/Styles';

export class Empty extends React.Component {
  static navigationOptions = {
    headerTitle: "Empty"
  };
  render() {
    return (
      <SafeAreaView>
        <StatusBar
        backgroundColor={AppStyles.colors.accentColor}
        barStyle={AppStyles.barStyle}
        />
        <Text>Empty screen.</Text>
      </SafeAreaView>
    );
  }
}

To style the UI, create a file in src/Styles called Styles.js, and add the following code.

const AppStyles = {
    colors: {
        accentColor: '#0084ff',
        inactiveGreyColor: '#626262',
        lightGreyColor: '#7f8c8d',
        separator: '#bdc3c7',
        white: 'white',
        black: 'black',
        grey: 'grey',
        green: 'green',
        onlineGreen: '#2ecc71',
        lightWhite: '#f9f9f9'
    },
    fonts: {
        FONT_REGULAR: 'Roboto-Regular',
        FONT_MEDIUM: 'Roboto-Medium',
        FONT_LIGHT: 'Roboto-Light',
        FONT_THIN: 'Roboto-Thin'
    },
    barStyle: "light-content"
};

export default AppStyles;

To create Facebook Messenger-styled navigation bars, we’ll be using react-navigation.

The top navigation bar will include “Messages,” “Active,” “Groups,” and “Calls” as a material-design-themed tab bar from react-navigation’s createMaterialTopTabNavigator. Create a file called Messages.js in the root folder and include the following code.

import { Platform } from 'react-native';
import { createMaterialTopTabNavigator, createAppContainer } from 'react-navigation';

import Empty from "../screens/Empty";

import AppStyles from '../styles/Styles';

export const Messages = createMaterialTopTabNavigator({
  MessagesScreen: {
    screen: Empty,
    navigationOptions: { header: null, title: 'Messages' }
  },
  ActiveScreen: {
    screen: Empty,
    navigationOptions: { header: null, title: 'Active' }
  },
  GroupsScreen: {
    screen: Empty,
    navigationOptions: { header: null, title: 'Groups' }
  },
  CallsScreen: {
    screen: Empty,
    navigationOptions: { header: null, title: 'Calls' }
  }
},
{
  tabBarPosition: 'top',
  tabBarOptions: {
    activeTintColor: AppStyles.colors.accentColor,
    inactiveTintColor: AppStyles.colors.inactiveGreyColor,
    pressColor: AppStyles.colors.lightGreyColor,
    labelStyle: {
      fontWeight: 'bold',
      fontSize: Platform.OS === 'ios' ? 11 : 12,
      fontFamily: AppStyles.fonts.FONT_MEDIUM
    },
    indicatorStyle: {
      backgroundColor: AppStyles.colors.accentColor
    },
    style: {
      backgroundColor: 'white'
    }
  }
});

If you export the Messages.js component into your App.js render, you will see the following.

TopBarFB

Next, build the base navigator of the app which includes a bottom tab navigation bar as well as the top bar that was just made. You can use Icon from react-native-elements as the tabBarIcon. However, these icons will be changed to BadgedIcons.

Create a file named Navigation.js inside src/Navigation and begin by adding the bottom icons.

import React from 'react';
import { createBottomTabNavigator, createAppContainer } from 'react-navigation';
import { Badge, Icon, withBadge } from 'react-native-elements'

import { Messages } from './Messages';

import AppStyles from '../styles/Styles';
import Empty from "../screens/Empty";

const MessagesIcon = ({ tintColor }) => (
  <Icon
    type="ionicon"
    name="ios-chatbubbles"
    size={24}
    color={tintColor}
  />
);
const UsersIcon = ({ tintColor }) => (
  <Icon
    type="material"
    name="supervisor-account"
    size={24}
    color={tintColor}
  />
);

const DiscoverIcon = ({ tintColor }) => (
  <Icon
    type="ionicon"
    name="md-compass"
    size={24}
    color={tintColor}
  />
);

As was done for the top bar, you can easily build a bottom navigation bar with icons by using createBottomTabNavigator.

const BottomTabNavigation = createBottomTabNavigator({
  MessagesScreen: {
    screen: Messages,
    navigationOptions: {
      header: null,
      tabBarIcon: MessagesIcon
    }
  },
  UsersScreen: {
    screen: Empty,
    navigationOptions: {
      header: null,
      tabBarIcon: UsersIcon
    }
  },
  DiscoverScreen: {
    screen: Empty,
    navigationOptions: {
      header: null,
      tabBarIcon: DiscoverIcon
    }
  }
},
{
  tabBarOptions: {
    showLabel: false,
    activeTintColor: '#0084ff',
    inactiveTintColor: AppStyles.colors.inactiveGreyColor,
    pressColor: '#7f8c8d'
  }
});

To include this navigation component in the application, first create a default export.

const Navigation = createAppContainer(BottomTabNavigation);

export default Navigation;

And then add it to the App.js file. The App.js file at this point should look as follows:

import React, { Component } from "react";
import Navigation from "./src/navigation/Navigation";
import PubNubReact from 'pubnub-react';

export default class App extends Component {
  constructor(props) {
    super(props);
    this.pubnub = new PubNubReact({
    publishKey: "INSERT-PUB-KEY-HERE",
    subscribeKey: "INSERT-SUB-KEY-HERE"
    });
    this.state = {
    };

    this.pubnub.init(this);
  }

  componentDidMount() {
    this.pubnub.subscribe({
      channels: ['channel1'],
      withPresence: true
    });
  }

  render() {
    return <Navigation />;
  }
}

Adding Badges to Icons

To use the react-native-elements badge, import it from `react-native-elements` in Navigation.js.

import { withBadge } from 'react-native-elements' 

Instead of the MessagesIcon, replace it with a BadgedIcon.

const MessagesBadge = withBadge(5)(Icon)

Note: you can pass in any count inside the first withBadge argument.

You can then change the Icon render to MessagesBadge.

const MessagesIcon = ({ tintColor }) => (
  <MessagesBadge
    type="ionicon"
    name="ios-chatbubbles"
    size={24}
    color={tintColor}
  />
);

You have now added a badge to the messages icon that looks as follows.

FullwithoutPresence

Active Users Badge

Throughout this tutorial, the badge count has been hard-coded for the MessagesIcon. However, you can make the UsersIcon badge update in real time by using PubNub Presence to find the number of users connected.

In App.js, after connecting to PubNub, you can have each client subscribe to a global channel. Then, with a Presence hereNow() call, you can retrieve the number of users connected. You can update this client's usersCount in the state and pass it into the navigation props, allowing you to access this value in the badge in real time.

Your App.js should now look as follows.

import React, { Component } from "react";
import Navigation from "./src/navigation/Navigation";
import PubNubReact from 'pubnub-react';

export default class App extends Component {
  constructor(props) {
    super(props);
    this.pubnub = new PubNubReact({
      publishKey: "INSERT-PUB-KEY-HERE",
      subscribeKey: "INSERT-SUB-KEY-HERE"
    });
    this.state = {
      userCount: 0,
    };

    this.pubnub.init(this);
  }

  componentDidMount() {
    this.pubnub.subscribe({
      channels: ['channel1'],
      withPresence: true
    });

    let presenceUsers;
    setInterval(() => {
      this.pubnub.hereNow(
      {
        includeUUIDs: true,
        includeState: true
      },
      (status, response) => {
        // handle status, response
        console.log(status);
        console.log(response);
        if (response != undefined) presenceUsers = response.totalOccupancy;
      }
    );
      this.setState({userCount: presenceUsers})
    }, 10000);
  }

  render() {
    return <Navigation screenProps={{userCount: this.state.userCount}}/>;
  }
}

In this code, setInterval() is used to continuously check the number of users joined every 10 seconds (you may change this for your needs). The user count is stored in the state and pass it through the Navigation component as a screenProp. When rendering the badged icon, it can be accessed from the screenProps as userCount.

As such, you need to change UsersScreen to include an icon as well as a badge. This is an alternative way to use the badge compared to how it was used for the messages badge.

UsersScreen: {
  screen: Empty,
  navigationOptions: ({ screenProps, navigation }) => ({
    header: null,
    tabBarIcon: () => (
      <View>
        <Icon
          type="material"
          name="supervisor-account"
          size={24}
        />

        <Badge
          value={screenProps.userCount}
          containerStyle={{ position: 'absolute', top: -4, right: -4 }}
        />
    </View>
    )
  })
},

Run the Application

You are now ready to run the application. You can simulate the app with iOS devices using the following command.

sudo react-native run-ios

For Android devices, you can simulate the application with the following command.

react-native run-android

Using PubNub's Debug Console, you can send messages to the application to display the updated notification badge updates with new messages and users in the application. You'll need to enter information for a few different fields, including your publish/subscribe keys, channel name ("channel1"), and a UUID for the users to be unique from each other. The application should function as follows:

ezgif com video to gif 4

What's Next

Congratulations, you have learned how to build a basic messaging app in React Native and add icons that update with new messages and users in real time using PubNub.

You can check out the completed version of the application on GitHub. If you would like to learn more about how to power your React applications with PubNub, be sure to check out PubNub's other React developer resources:

If you have any other questions or concerns, please feel free to reach out to devrel@pubnub.com.

More from PubNub

How to Add a Notification Badge to Icons in React Native
Real-time Chat BlogDec 19, 20226 min read

How to Add a Notification Badge to Icons in React Native

Display real-time notification badges with PubNub and React Native to display important information and bring users back to your...

Michael Carroll

Michael Carroll

Digital Twins and the Future of Real-Time Data
InsightsDec 6, 20224 min read

Digital Twins and the Future of Real-Time Data

The concept of Digital Twins has evolved over the last two decades, however, one thing remains the same: the need for real-time...

Michael Carroll

Michael Carroll

How Many Text Characters Fit in a 32KB PubNub Message?
Real-time Chat BlogNov 24, 20224 min read

How Many Text Characters Fit in a 32KB PubNub Message?

Learn the ins-and-outs of PubNub message size and get a better idea of how many text characters fit in a single message.

Michael Carroll

Michael Carroll