Skip to content

WebNinjaDeveloper.com

Programming Tutorials




Menu
  • Home
  • Youtube Channel
  • Official Blog
  • Nearby Places Finder
  • Direction Route Finder
  • Distance & Time Calculator
Menu

React.js Firestore Project to Build Public Chat Messenger With Authentication in Browser Using Javascript

Posted on October 4, 2022

Welcome folks today in this blog post we will be building a public chat messenger in react.js using firestore database with authentication in browser using javascript. All the full source code of the application is given below.

 

 

Get Started

 

 

In order to get started you need to a empty react.js project by executing the below command

 

 

npx create-react-app firestorechat

 

 

cd firestorechat

 

 

Installing Dependencies

 

 

Now we will install the required dependencies for this react.js chat project which are as follows

 

 

  1. Material UI Core
  2. Firebase
  3. React Firebase Hooks

 

 

npm i firebase 

 

npm i @material/ui-core

 

npm i material-ui

 

npm i react-firebase-hooks

 

 

Folder structure for this project

 

 

First of all let’s see the folder structure and the required files required for this project

 

 

 

 

Getting Firebase Credentials

 

 

Now we will be getting the firebase credentials for this chat firestore project. First of all create a Firebase account and create a new project and go to the project settings and create a web app and get the required below code as shown below in the picture

 

 

 

 

Now create a firebase.js file inside the root directory of your react.js project and copy paste the below code

 

 

firebase.js

 

 

TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import firebase from 'firebase'
 
const firebaseApp = firebase.initializeApp({
    apiKey: "",
    authDomain: "",
    databaseURL: "",
    projectId: "",
    storageBucket: "",
    messagingSenderId: "",
    appId: ""
})
 
const db = firebaseApp.firestore()
 
const auth = firebase.auth()
 
export { db, auth }

 

 

In the above code you need to copy paste your config information of the firebase account. Here we are importing the firebase dependency and then we are calling the firestore method and also importing the auth method for authentication. Lastly we are exporting the auth and db variables from this config file.

 

 

Enable the Google SignIn Method

 

 

Now we need to go to the Authentication tab and inside the sign in methods go to google authentication and enable the sign in method of google as shown below

 

 

 

 

 

Enabling the Firestore Database

 

 

Now we need to enable the firestore database as well after that edit the rules and copy paste the below rules inside it section as shown below

 

 

1
2
3
4
5
6
7
8
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write
    }
  }
}

 

 

 

 

 

Now you need to copy paste the below code inside the App.js file of your react.js project.

 

 

App.js

 

 

TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import './App.css';
import Chat from './components/Chat';
import SignIn from './components/SignIn';
import { auth } from './firebase.js'
import { useAuthState } from 'react-firebase-hooks/auth'
 
function App() {
  const [user] = useAuthState(auth)
  return (
    <>
      {user ? <Chat /> : <SignIn />}
    </>
  );
}
 
export default App;

 

 

As you can see we are importing the required firebase react hooks to check the state of the authentication of user whether the user is logged in or not. If the user is logged in then we will show the chats component and if not we will show the login page. Now we need to make the required components in the next step.

 

 

Creating the Components

 

 

Now create a components folder inside the react.js project and inside it first of all make a SignIn.js Component where we will have a login button to allow users to sign with their google account

 

 

Components/SignIn.js

 

 

TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import React from 'react'
import firebase from 'firebase'
import { auth } from '../firebase.js'
import { Button } from '@material-ui/core'
 
function SignIn() {
    function signInWithGoogle() {
        const provider = new firebase.auth.GoogleAuthProvider()
        auth.signInWithPopup(provider)
    }
    return (
        <div style={{ display: 'flex', justifyContent: 'center', height: '100vh', alignItems: 'center' }}>
            <Button style={{ padding: '30px', fontSize: '20px', borderRadius: '0', fontWeight: '600' }} onClick={signInWithGoogle}>Sign In With Google</Button>
        </div>
    )
}
 
export default SignIn

 

 

As you can see we are using the google sign in authentication here. We have a simple login with google button rendering in the browser. When the user click on the button a popup window will appear containing all the google accounts of the user. If the user selects any individual account then it will redirect the user to the chats component.

 

 

 

 

Now we will be building the Chat.js component to render the input field where the user will enter the chat messages and also it will render all the messages which are entered by the user and it will extract it from firestore database.e

 

 

Components/Chat.js

 

 

TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import React, { useState, useEffect, useRef } from 'react'
import { db, auth } from '../firebase'
import SendMessage from './SendMessage'
import SignOut from './SignOut'
 
function Chat() {
    const scroll = useRef()
    const [messages, setMessages] = useState([])
    useEffect(() => {
        db.collection('messages').orderBy('createdAt').limit(50).onSnapshot(snapshot => {
            setMessages(snapshot.docs.map(doc => doc.data()))
        })
    }, [])
    return (
        <div>
            <SignOut />
            <div className="msgs">
                {messages.map(({ id, text, photoURL, uid }) => (
                    <div>
                        <div key={id} className={`msg ${uid === auth.currentUser.uid ? 'sent' : 'received'}`}>
                            <img src={photoURL} alt="" />
                            <p>{text}</p>
                        </div>
                    </div>
                ))}
            </div>
            <SendMessage scroll={scroll} />
            <div ref={scroll}></div>
        </div>
    )
}
 
export default Chat

 

 

As you can see we have the input field first of all to allow the user to enter the message and then we have a button on the right hand side to submit the form. When we submit the form and enter automatically message is passed to a separate component which we will make which is called as SendMessage.js here we are passing a scroll parameter to it. Scroll parameter is assigned a useRef() hook.Inside this sendMessage component we will insert the message inside the firestore database and automatically the height of the scrollbar or window will increase. It will automatically scroll down the window when you type a new message or receive a new message from the other User

 

Now we will write this New component which is called SendMessage.js inside the components folder

 

 

Components/SendMessage.js

 

 

TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import React, { useState } from 'react'
import { db, auth } from '../firebase'
import firebase from 'firebase'
import { Input, Button } from '@material-ui/core'
 
function SendMessage({ scroll }) {
    const [msg, setMsg] = useState('')
 
    async function sendMessage(e) {
        e.preventDefault()
        const { uid, photoURL } = auth.currentUser
 
        await db.collection('messages').add({
            text: msg,
            photoURL,
            uid,
            createdAt: firebase.firestore.FieldValue.serverTimestamp()
        })
        setMsg('')
        scroll.current.scrollIntoView({ behavior: 'smooth' })
    }
    return (
        <div>
            <form onSubmit={sendMessage}>
                <div className="sendMsg">
                    <Input style={{ width: '78%', fontSize: '15px', fontWeight: '550', marginLeft: '5px', marginBottom: '-3px' }} placeholder='Message...' type="text" value={msg} onChange={e => setMsg(e.target.value)} />
                    <Button style={{ width: '18%', fontSize: '15px', fontWeight: '550', margin: '4px 5% -13px 5%', maxWidth: '200px'}} type="submit">Send</Button>
                </div>
            </form>
        </div>
    )
}
 
export default SendMessage

 

 

Now you can see we have a simple input field and a button inside this component. We have a form element and we have attached a onSubmit event handler to the form. Whenever you click the send message button this event will trigger and after that inside that sendMessage() function we are getting the message value and inserting to firestore database. Here we are creating the collection or table inside firestore database which is called as messages and also we are also getting the user id and profile picture from google account object.

 

Now if you check your firebase dashboard area a new user will be entered like this as shown below

 

 

 

 

Styling the Chat App

 

 

Now guys for the styling just copy paste these css styles inside your App.css file of your react.js chat project

 

 

App.css

 

 

CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
img {
  border-radius: 50%;
  height: 45px;
  margin-top: -20px;
  border: 2px solid black;
}
 
p {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
  font-weight: 500;
  font-size: 25px;
  margin-top: 10px;
  margin-left: 10px;
  margin-right: 10px;
  overflow-wrap: break-word;
}
 
.msg {
  display: flex;
  padding: 20px 10px 0 20px;
  margin: 20px;
  border-radius: 3000px;
  box-shadow: 0 0 10px rgb(164, 164, 164);
  align-items: center;
}
 
.sent {
  background-color: #395dff;
  color: white;
  border-top-right-radius: 1000px;
  flex-direction: row-reverse;
  padding: 20px 20px 0 10px;
  text-align: end;
  float: right;
}
 
.received {
  border: 1px solid lightgray;
  background-color: #FAFAFA;
  border-top-left-radius: 1000px;
  float: left;
}
 
.sendMsg {
  position: fixed;
  display: flex;
  width: 100%;
  bottom: 0;
  z-index: 1;
  border-top: 1px solid lightgray;
  margin-left: -5px;
  padding: 10px;
  padding-bottom: 30px;
  background-color: #fafafa;
}
 
.msgs {
  margin: 110px 0;
  display: flex;
  flex-direction: column;
}
 
 
@media (max-width: 775px) {
  p {
    font-size: 20px;
  }
  .sent {
    padding: 10px 10px 0 10px;
  }
  .received {
    padding: 10px 10px 0 10px;
  }
  img {
    height: 35px;
    margin-top: -10px;
  }
}
 
@media (max-width: 500px) {
  p {
    font-size: 15px;
  }
  .sent {
    padding: 7px 7px 0 7px;
  }
  .received {
    padding: 7px 7px 0 7px;
  }
  img {
    height: 30px;
    margin-top: -7px;
  }
}

 

 

And also if you try to send a message then this message will be shown inside the firestore database as shown below. A new collection will be created automatically

 

 

 

 

 

 

As you can see inside this figure we have also a signout button also appearing inside the picture for that just create a SignOut.js component also like this

 

 

Components/SignOut.js

 

 

TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import React from 'react'
import { auth } from '../firebase.js'
import { Button } from '@material-ui/core'
 
function SignOut() {
    return (
        <div style={{
            display: 'flex', justifyContent: 'center', position: 'fixed', width: '100%', backgroundColor: '#FAFAFA', top: 0, borderBottom: 'solid 1px lightgray', zIndex: '10'
        }}>
            <Button style={{ padding: '20px', fontSize: '15px', borderRadius: '0', fontWeight: '600' }} onClick={() => auth.signOut()}>Sign Out</Button>
        </div>
    )
}
 
export default SignOut

 

 

Here for the signOut process we are justing the auth.signOut() method which is provided by firebase to actually signout a user.

 

 

Recent Posts

  • Android Java Project to Merge Multiple PDF Documents From Gallery Using iTextPDF Library
  • Android Java Project to Detect System Hardware & System CPU Info & Display inside TextView Widget
  • Android Java Project to Integrate Google OAuth2 Login & Logout System & Save User Info in SharedPreferences
  • Android Java Project to Export Raw Text to PDF Document Using iTextPDF Library
  • Android Java Project to Export Images From Gallery to PDF Document Using iTextPDF Library
  • Angular
  • Bunjs
  • C#
  • Deno
  • django
  • Electronjs
  • java
  • javascript
  • Koajs
  • kotlin
  • Laravel
  • meteorjs
  • Nestjs
  • Nextjs
  • Nodejs
  • PHP
  • Python
  • React
  • ReactNative
  • Svelte
  • Tutorials
  • Vuejs




©2023 WebNinjaDeveloper.com | Design: Newspaperly WordPress Theme