User online presence with PubNub
Nik Vogrinec
14 November, 2020 ยท 10 minute read
The Gist
In one of my recent projects I had to implement user presence and chat, I thought it was an interesting idea to explore real-time user presence. You can expand on this tutorial by adding notifications, real-life chat, and many other things!
Let's say that we want to see users that are currently on our webpage in real-time. For that we are going to use PubNub's API, React and a react-pubnub wrapper which will simplify our work.
Requirements
Any type of fresh React project (NextJS, Gatsby, create-react-app);
PubNub API keys (Publish & Subscribe key);
A computer to work on would be helpful :)
Let's get started
Firstly I would recommend you get a hold of your PubNub API keys from the official pubnub site. It requires you to create a new account, but it is free to use for our little project - no credit card required!
Next up, create a new react project with your desired technology. I just used create-react-app boilerplate.
Now, we are going to install both the PubNub package & the react pubnub wrapper with:
yarn add pubnub pubnub-react
or
npm i pubnub pubnub-react
Connecting PubNub back-end to our React application
Now we are really going to need those PubNub API keys! So get them if you don't already have them.
We are going to create a new instance of the PubNub class with those keys. Please note that it is highly recommended that we create a pubnub instance where we have access to our root element, because we will need to add a provider that is going to encapsulate the root element.
Also, please do not use the keys that I have provided since keys are unique to each account and use your keys instead. I will also disable the keys you see after this blog is finished.
Next up we need to encapsulate our root element <App /> in my case with PubNub provider which comes from the pubnub-react package and add a client which is our instantiated PubNub class.
And that's it - the connection at least ๐.
Logistic flow
The global channel is something we need to create, in pubnub we can have multiple channels that we use for chat. You don't have to name it global, but I prefer to do it this way because it's more obvious what it does.
So here's how it is going to work on our simple application: A user connects to our application, he/she enters his/her name and gets added to the global channel and sees all other users that are currently online.
Here's how it would work on an application with authentication: User logs in / registers then gets added to a global channel with his/her name which we can get from the back-end or directly from the front-end if he/she is just registering.
PubNub uses uuid's to identify users, if we don't specify a uuid it is just going to use a randomly generated one which we don't want since we won't be able to know which user is which. That is why we are going to use the users' name as an identifier.
Of course, the user does not need to be authenticated to actually see the presence of other users. For that, we just skip the authentication process altogether, but instead just listen to changes in the global channel.
This is how our application looks now, with no pubnub logic!
Adding users to a global channel
First, let's gain access to PubNub class using the usePubNub hook from pubnub-react package.
Now that we have access we can set the user identifier and subscribe them to the global channel.
And that's it, whenever our user types in his/her name it will add him/her to the global channel.
Displaying Present Users
Now we need to actually display users that are currently present. We can do that by mounting the hereNow method from the pubnub class which checks every few milliseconds who is currently present. I do not want it to check so often, that's why I put the function inside of a 2-second interval.
Our onlineUsers state now updates every two seconds with the list of online users. We then loop over that list and display their names.
Unsubscribing users
At the moment our presence is working very well, it displays the online users, but the issue we are facing now is actually unsubscribing when a user leaves the application. There is a timeout set at 5 minutes which will unsubscribe the user from all channels, but I want it to update quicker than that.
Let's go into our root file and add a quick method which will do exactly that!
Here we do not need to call the usePubNub hook since we have direct access to the class in the root file.
In case you're in NextJS or Gatsby you can put the event listener inside the useEffect block and it will work just as well.
Conclusion
PubNub is an amazing collection of API's, it's not just for presence, but you can use it for multiple real-time stuff! I've also created a GitHub repository, check it out!