Making a Web plus Mobile Chat App from Scratch with your own Server using Pusher
HOLA GUYS! In this blog, I’m going to walk you through the making of a chat app using ReactJS( for web ), React-Native( for mobile ) and NodeJS( for server). We won’t use any external API to handle our chat messages, everything will be done by the server itself. However, to enable a realtime messaging service we will use Pusher : a platform that allows developers to easily build an application with realtime features. I assume that you have a basic knowledge of the three platforms i.e ReactJS, React-Native and NodeJS which we are going to use in this project. I will discuss only the major functionalities and not each and every bit of code here, so if you get stuck anywhere, follow the github link provided for each project.
Here are the functionalities that we are going to integrate into our chat app :
- Registering a user with username, email, password and imageURL.
- Signing in the user with email and password.
- Sending Friend Request to his/her friend registered in the app.
- Accepting Requests which are sent by his/her friends.
- Realtime-Chatting with friends.
I have divided this project into three parts :-
- Making of ReactJS web app : Discussed in this blog. Its github repo can be found here.
- Making of NodeJS server : Discussed in Making a NodeJS Server for Chat App. Its github repo can be found here.
- Making of React-Native mobile app : Discussed in Making a React-Native Chat App. Its github repo can be found here.
Making the ReactJS Web App
This App which you can see here has an awesome UI, all because of “Tachyons” which helps a lot to place components at right place and styling them perfectly. We will be using npm to install our required modules and creating and running the project. Make the project using “create-react-app project-name” command. I named it “Chatter”. You can name it whatever you want.
Handling Navigation in App.js
Starting with the App.js file, we will handle the navigation and the basic info of the logging in user here. Here is the code for it :
We want the initial page to be a signin page so in the initial state, put ‘signin’ as the selected route. Define two methods in it i.e ‘onRouteChange’ to change the routes(navigation between different screens) and ‘loadUser’ to load the data coming from the server of the logging in user. The render method will return one of the three screens (register, signin and mainscreen) depending on the value of the route. We will pass both of the methods in SignIn and Register Components as props and will use them accordingly inside them.
Sign-Up and Sign-In page
Now, let’s create the Login and SignUp page. You can design them in whatever way you want. What we need in the SignUp page are four text-inputs for taking username, email, password and imageURL and one button to finally register the user. Along with this, you should also have a button to direct the user to the login page if he is already registered. To make it more interactive, you can add an image component in it to show the image given by the imageURL pasted by the user. Paste URL of a simple user-photo in the initialized state in the register component and set the state of imageURL to the URL provided by the user whenever he paste an URL in the corresponding text-box. Here is the Register page in my Chatter App :
The method to be called upon by clicking the Register button is shown below :
Here we are registering a user by passing the data to our server and the server in response is giving us data i.e name, imageURL and email if the user successfully gets registered and sends an error if not. Initially, the user will not have any friends so we are making a NULL list by ourselves and passing them to the loaduser method which was passed as props to Register components from App.js. Also, we are setting the route name to ‘home’ to go to the home screen. In the same way, we can make our sign-in component.
Now from App.js, we pass two props to our MainScreen component i.e the data of the signing in/registering user and ‘onRouteChange’ method to logout the user from inside MainScreen. Now let’s code our ‘MainScreen’ to implement the chat and other functionalities.
Coding the Main-Screen
The MainScreen will have contacts loaded at one side and the other part will show either the chat screen or the friend request screen or the list of all users to send them friend request. What will be shown will be handled by a state variable in the same way we did route changing in App.js. Let the state variable name be ‘branch’ and it will handle our screens within the main screen.
Handling the Contact List
The contact list will be displayed at the left side of the screen as shown above. This contact list was sent to the MainScreen using props from App.js. And here, we will use list.map() function to render the complete list. First make a Scroll.js component to enable scrolling wherever we have a list to display. The Scroll.js component is as shown below:
We will put our list component inside it to make it scrollable.
Note here that if our friendlist is NULL, we will simply show a messsage. But if the user have friends, then that list is passed to CardList component. The CardList component is shown below :
Note here that we are using the list.map() function and rendering each data of Cardlist inside different Card components. Here, since we are using the same Card layout to display AllUserList and FriendRequestList, we are passing a parameter “friend” to change the layout a little bit. The Card component is shown below.
Here we have three methods inside the Card component, fillchat(), confirm() and follow(). For a simple friend listed in friendlist as shown in the above picture, we need to load the previous chat we had with this friend in the right area as shown in the very first picture. For this we have fillChat() method which calls the loadChattingUser() method of the MainScreen(Contact.js) which we passed as props to the Card component. The loadChattingUser method is shown below :
Here, this method sets the friend’s name, imageURL, email and database name to the clicked friend’s data and makes a call to the server to fetch the messages. The obtained response from the server is a list of messages along with the name to know who sent the message. The message sent by the user itself are displayed on the right side with a black background and those sent by the friends on the left side with a green background. Down there in that space we have our functionality to send a message which contains an input box to write the message and a button to send it. Upon clicking the send button, updateMsgingChat() method is called which makes a call to the server, add message to the database and in response get the message list back and the message list is updated in the state. We also need to do one more thing here. We have to reshuffle the order of our friendList because now the person to whom we are chatting should be placed at the top. To do this, we simply make a request to the server fetching the contacts of this user which have already got updated in the database on the basis of last modified entry and we then set the friendList to the response we get from the server.
Integrating Pusher for Realtime Connection
Now let’s discuss the most important functionality of this app i.e enabling the realtime messaging. WAIT! But what is realtime messaging? See in the above funtionality of sending message, the message will be sent to the server only, it will not be displayed on the screen of other user until unless a call is made from his app to the server. What we need is that as soon as we send the message, that message should also be send to the other user and my contact information should get placed at the top in his contact list because most recent message sent to him is mine. For this, we will use Pusher : a platform that allows developers to easily build an application with realtime features. To use Pusher in your app, you will have to make a pusher account and will have to create a new channel app. It will ask you about your front-end and back-end tech. Select React as front-end and Node as back-end (since we are going to make a NodeJS server) and click “OK” button. That’s all, you will be provided with the corresponding code you have to add in your app and server to enable realtime features. Now lets us understand how to add it and how will it work :
- First of all, add the script for pusher inside your index.html file.
2. Install Pusher using npm (or yarn) using command :
npm i pusher-js
and import it in the required file like this
import Pusher from ‘pusher-js’;
3. We have to open a connection to our Pusher whenever our app starts and we have to subscribe to a channel. This can be done using the following snippet of code placed in componentDidMount() method of that component :
One thing to note here is the channel name. We assign different channels to different users because this will ensure that when message is sent to one user say to ‘A’ then ‘B’(the other user) will not get notified of it, only ‘A’ has to be notified. We are making the channel name using the email of the logged-in user concatenated with the string “-channel”.
4. Finally, we will bind a function to an event (we don’t have to distinguish events because we will use this channel only for notifying the user about a message sent by someone). We will simply call this event as ‘my-event’. Now what will happen is, whenever someone will message us, the server will notify front-end about the messaging by running the function attached to the event of this channel and inside this function, we will make a call to the server to fetch the message data and the reshuffled contact list and will load here in the front-end. So as soon as someone messages us, our contact list and the message data will get updated. This is the realtime functionality we wanted to achieve. Here is the function attached to the event “my-event” :
With this, we have completed our messaging functionality. Alternatively, you can also follow this Pusher guide to add pusher in your app.
Let us now integrate the functionality of sending and accepting friend requests.
Sending Friend Requests
What we need in this part is displaying the list of all users registered in server so that we can send them friend requests. So we will simply make a call to the server, fetching data of all users and display them in a list. To minimize code, we will use the same card we used to display our contact list. We will add just one more button in the card to send the friend request to that user. Remember the state variable ‘parameter’ we passed in our CardList component, it will be used to differentiate the cards. If the parameter passed is “searchfrnds” we will display the button for sending a friend request and the list passed will be the one having all registered user’s info in it. If the parameter is “Confirm”, the button will be Accepting friend request button and the list will be info of all those users who have sent us the friend request. Don’t worry about the lists, they all will be handled in the server which we will code in next part. We just have to make calls to the server and fetch the required data. The all user page is as shown below :
Upon clicking the follow button, we will call the follow method of Card.js. This method makes a call to server sending the name of user from whom the request is made to the user who is requested. The server will add the name of this user in the friend request list of other user and when user will accept the request, the two of them will become friends.
Accepting Friend Requests
This is the final major functionality of our app. It is almost similar to sending friend request functionality. Here is the screen for it :
Here also we will use the same card we used for the contact list. We just have to add the “Confirm” button. The list of users who have requested us will be fetched from the server and we will display it here. Upon clicking the Confirm button, the Confirm method will be called, the server will be notified of the confirming and the two users will finally become friends.
Remaining minor functionalities
The remaining functionalities you can add yourself, or if you find difficulty anywhere, feel free to ask in the comment section. I have also provided the github link for this project to help you with coding. Also, finally you will have to host the App on Heroku or some other platform of your choice so that other can use it and see your project. Mine is hosted here if you want to see it. To make the project functional, you will have to make a server also. To code the node server, follow the second part of this tutorial.
And there you go! You have finally completed the Web Chat App made using ReactJS with an awesome UI.