An open API service indexing awesome lists of open source software.

https://github.com/okhuaroboosayuki/counter-app

A React counter app created with firebase authentication and Context API
https://github.com/okhuaroboosayuki/counter-app

firebase-auth react-components react-hooks react-router reactjs reducer usecontext useeffect usereducer usestate

Last synced: 12 months ago
JSON representation

A React counter app created with firebase authentication and Context API

Awesome Lists containing this project

README

          

# Counter app built using Reactjs and Firebase

[![AltSchool Badge](https://img.shields.io/badge/-Engineering-6773E5?style=for-the-badge&logo=data:image/png;base64,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&logoColor=white&link=https://altschoolafrica.com/schools/engineering)](https://altschoolafrica.com/schools/engineering)

## Table of contents

- [Overview](#overview)
- [Built with](#built-with)
- [Features](#features)
- [Feature added](#feature-added)
- [Possible features to add](#possible-features-to-add)
- [Links](#links)
- [Author](#author)

## Overview

![Counter App](/src//assets/images/fullpage.png "Counter")

This project is a solution to task given by [AltSchool Africa](https://www.altschoolafrica.com/). A counter application is a basic program that displays a default count of zero ("0"). It allows the user to input a numerical value, as well as to increment, decrement, and reset the count. The application features a navigation bar that includes an active state, which can be used to navigate to the home page, the 404 error page, the Error Boundary page, the CounterWithCustomHook, and the CounterWithReducer page. This provides an easy and intuitive way for the user to navigate through the different sections of the application quickly. Its functionality is limited to keep the app simple in nature.

![Counter App](/src/assets/images/count%20navbar.png "Counter navigation")

## Built with

- [CSS](https://www.w3schools.com/css/)
- [Reactjs](https://reactjs.org/)
- [react-router-dom](https://reactrouter.com/en/main)
- [react-error-boundary](https://reactjs.org/docs/error-boundaries.html)
- [react-helmet-async](https://www.freecodecamp.org/news/react-helmet-examples/)
- [Custom Hook](https://reactjs.org/docs/hooks-custom.html)
- [useReducer](https://reactjs.org/docs/hooks-reference.html#usereducer)
- [useContext](https://reactjs.org/docs/hooks-reference.html#usecontext)
- [firebase authentication](https://firebase.google.com/docs/auth/web/start)

## Features

The primary features of the application include increment, decrement, reset, and setValue capabilities. These capabilities were implemented using both a custom hook and a useReducer. This implementation approach resulted in the creation of two distinct pages, one for the custom hook and the other for the useReducer.

### a custom hook feature

A custom hook function was developed to manage the increment, decrement, reset, and setValue operations. This custom hook serves as a reusable piece of logic that encapsulates the functionalities, enabling it to be easily shared across different components.

```js
import { useRef, useState } from "react";

const useCounter = () => {

const [count, setCount] = useState(0);

const inputRef = useRef();

const increment = () => {};

const decrement = () => {};

const reset = () => {};

const setValue = () => {};

return [count, increment, decrement, reset, setValue, inputRef];
};

export default useCounter;
```

Once created, the custom hook function was imported into the CounterWithCustomHook component, which utilized its functionality to manage the state of the counter app. This made it easy for the CounterWithCustomHook component to share the same state management logic as the custom hook and have the same set of functionalities as the custom hook.

### a useReducer feature

A reducer function was created to handle the increment, decrement, reset, and setValue operations. This function serves as a centralized location to manage the state transitions of these functionalities.

```js
import { useReducer } from "react";

const useCounterReducer = () => {
const initialState = {
count: 0,
};

const reducer = (state, action) => {
switch (action.type) {
case "increment":
return {};
case "decrement":
return {};
case "reset":
return {};
case "setValue":
return {};
default:
return state;
}
};


const [state, dispatch] = useReducer(reducer, initialState);

return [state, dispatch];
};

export default useCounterReducer;

```

Once created, the reducer function was imported into the CounterWithReducer component, which utilized its functionality to manage the state of the counter app.

The custom hook and the useReducer features carry out the same functionality.

## Feature added

### firebase authentication feature

The application appears to be standard at first glance. However, to enhance the functionality of the app, Firebase was integrated. To implement Firebase, the web application was first registered on the Firebase console. Afterwards, a configuration file was created to pass in the Firebase configuration settings and initialize the application.

```js
import { initializeApp } from "firebase/app";
import { getAuth, GoogleAuthProvider } from "firebase/auth";

const firebaseConfig = {
apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.REACT_APP_FIREBASE_APP_ID,
};

const app = initializeApp(firebaseConfig);

export const auth = getAuth(app);

export const googleProvider = new GoogleAuthProvider();

```

### useContext feature

To maintain a clean and organized codebase, the Context API was employed to create and provide a context object that includes callback functions for user authentication. This includes functionality for signing up with email and password, logging in with email and password, logging out, and signing in or signing up with Google. By utilizing the Context API, these functions can be easily shared and accessed across different components in the application, while keeping the codebase organized and manageable.

```js
import { createUserWithEmailAndPassword, onAuthStateChanged, signInWithEmailAndPassword, signInWithRedirect, signOut } from "firebase/auth";
import { createContext, useEffect, useState } from "react";
import { auth } from "../assets/config/firebase";

export const AuthContext = createContext();

export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState()
const [loading, setLoading] = useState(true)

function signup(auth, email, password) {
return createUserWithEmailAndPassword(auth, email, password)
}

function login(auth, email, password) {
return signInWithEmailAndPassword(auth, email, password)
}

function logout() {
return signOut(auth)
}

function googleSignIn(auth, googleProvider) {
return signInWithRedirect(auth, googleProvider)
}

useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (user) => {
setCurrentUser(user)
setLoading(false)
})

return unsubscribe
}, [])

const value = {
currentUser,
signup,
googleSignIn,
login,
logout,
}

return(

{!loading && children}

)
}
```

With the introduction of the Context API, a registration page was developed to allow users to sign up using their email and password or their Google accounts, which are then sent to Firebase for validation.

![Counter App](/src/assets/images/counter%20signIn.png "sign up page")

Once the user has successfully signed up, they are redirected to the login page where they can enter their credentials to gain access to the application. While this process is underway, the application sends a mail to the user's email address containing a link for authentication. The user needs to click on the link to confirm the email is theirs, this verifies the authenticity of the email address and authenticate the user. This feature provides an extra layer of security for the application and ensures that only legitimate users are granted access.

![Counter App](/src/assets/images/counter%20logIn.png "login page")

if a user is authenticated and logged in, the user can access the counter app, else the user will be redirected to the login page. If the user logs in with a Google account, the user's name and photo are displayed to personalize the experience. On the other hand, if the user logs in with an email and password, only their email address will be displayed. This distinction is made to safeguard user's personal information, and also give a better personalized experience. Additionally, this is a good practice to follow because it ensures that the user only sees the necessary information, without compromising on the security.

#### when user is logged in with google

![Counter App](/src/assets/images/logged%20in%20with%20google.png "logged in with google")

#### when user is logged in with email and password

![Counter App](/src/assets/images/logged%20in%20with%20email.png "logged in with email")

When the user logs out, the user is redirected back to the login page.

## Possible features to add

The following are some examples of potential features that could be added to the application:

- A function that confirms if the user has been authenticated via the link sent to the user's mailbox
- A feature that allows the user to reset their password
- A feature that allows the user to update their email address

## Links

- Solution Code URL: [React-Counter-App-Code](https://github.com/okhuarobo-osayuki/counter-app)
- Live Site URL:
- Link to article written: [Counter app built using Reactjs and Firebase](https://medium.com/@osayukir/counter-app-built-using-reactjs-and-firebase-26a55f1d4903)

## Author

[![GitHub Badge](https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white&link=https://github.com/okhuarobo-osayuki)](https://github.com/okhuarobo-osayuki)
[![Twitter Badge](https://img.shields.io/badge/-@osayuki__-1ca0f1?style=for-the-badge&logo=twitter&logoColor=white&link=https://twitter.com/osayuki__)](https://twitter.com/osayuki__)
[![Linkedin Badge](https://img.shields.io/badge/osayukiokhuarobo-blue?style=for-the-badge&logo=Linkedin&logoColor=white&link=https://www.linkedin.com/in/osayuki-raymond-okhuarobo/)](https://www.linkedin.com/in/osayuki-raymond-okhuarobo/)