An exact clone of youtube with all functionalities from View count to Subscribe to everything (Without Youtube Api) Using Firebase, FFmpeg, And React
Note:
Following are the different parts of this project in order:
Part 1 Ā ā Intro to the Project and Features ExplanationPart 2 Ā ā Create the skeleton of the app from adding redux to adding all screens with dummy data and at last adding routesPart 3 Ā ā Adding Firebase to our App, Creating Context Api, Completing Authentication Login from the web (This Article)
Iāll update the order as we Move on :))
Github Code
Again for new viewers, The Github code has been uploadedĀ
https://github.com/harsh317/Youtube-CLone-ReactJs
What We Gonna go in this Part
So in this part First letās add firebase to our app then we can create the firebase Context API. Weāll implement the Entire Authentication system of firebase and complete our context file.Ā With that being said, Letās get started !!
Creating And Initialising Firebase project AND Configuring For Basic Authentication functions
First, quickly go toĀ
You should see something like this
Enabling FireStore Database
Now letās enable the firestore database for our app. Click on the Firestore database or directly go to thisĀ
Next on the right- side click on āCreate databaseā ā Select a starting mode for your Cloud Firestore Security Rules (I will clickĀ Test modeĀ for now) ā Select aĀ
Test Mode
*Good for getting started with the mobile and web client libraries, but allows anyone to read and overwrite your data. After testing,Ā **make sure to review theĀ
Secure your data *section. https://firebase.google.com/
**
With that our firebase should look like this with default Test rules which we will change later:
Enabling Authentication
Now, similarly, click on the Authentication tab in the sidebar or directly go to thisĀ
Click on āGet Startedā and you will be presented with the āGet started with Firebase Auth by adding your first sign-in methodā Screen. Letās Add the Providers we need
Adding Email/Password Provider
Just click on the Email/Password Provider And further, click on theĀ Email/Password check boxĀ and click on theĀ Save button
Adding Google Provider
Then just add a new provider and in the Additional providers, column click on āGoogleā provider. And further, click on theĀ GoogleĀ check boxĀ and change the following settings. Finally, click on the āSaveā button
When you got the following 2 statuses enabled, we are ready to go!
And with that ig we are finished setting up Firebase. Now, letās makeUp the Context API. :)
Creating out Firebase Context API For Basic Authentication Functions
If you donāt know about context API, I recommend checking about them more. Here is more basic meaning from theĀ
Context provides a way to share values like these between components without having to explicitly pass a prop through every level of the tree.Context is designed to share data that can be considered āglobalā for a tree of React components, such as the current authenticated user, theme, or preferred language
So, letās move ahead further without wasting any more time. In the Src folder, create a āContextā folder and create the context file with maybe a better file name unlike me ; ā ;
Basic UserAuthContext File with Basic Login Functions
import React, { useContext, useState, useEffect } from "react";
import {
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
onAuthStateChanged,
signOut,
GoogleAuthProvider,
signInWithPopup,
} from "firebase/auth";
import { doc, setDoc } from "firebase/firestore";
import { db, auth } from "../Config/FirebaseConfig";
const AuthContext = React.createContext();
export const useAuth = () => {
const auth = useContext(AuthContext);
return { ...auth, isAuthenticated: auth.CurrentUser != null };
};
export function AuthProvider({ children }) {
const [CurrentUser, setCurrentUser] = useState();
const [loading, setloading] = useState(true);
useEffect(() => {
const unsuscribe = onAuthStateChanged(auth, (user) => {
console.log(user);
setCurrentUser(user);
setloading(false);
});
return unsuscribe;
}, []);
const SignupUser = (email, password, name) => {
return createUserWithEmailAndPassword(auth, email, password).then(
(resp) => {
if (resp.user) {
CreateFireStoreUser(
resp.user,
name,
"https://cdn-icons-png.flaticon.com/512/149/149071.png"
);
}
}
);
};
const CreateFireStoreUser = (user, name, profileImage) => {
const UsersRef = doc(db, "Users", user.uid);
setDoc(UsersRef, {
name: name,
profileImage: profileImage,
initials: name[0] + name[name.length - 1],
Suscribers: [],
}).then(() => {
console.log("added User");
});
};
const LogInUser = (email, password) => {
return signInWithEmailAndPassword(auth, email, password);
};
const SignInWithGoogle = () => {
const provider = new GoogleAuthProvider();
return signInWithPopup(auth, provider);
};
const logout = () => {
return signOut(auth);
};
const value = {
CurrentUser,
SignupUser,
LogInUser,
logout,
ResetPassword,
CreateFireStoreUser,
};
return (
<AuthContext.Provider value={value}>
{!loading && children}
</AuthContext.Provider>
);
}
Yup, we have Our Basic Context File ready for simple and basic functions like Signup/login(With Email Password), creating a Firestore user when the user is signing up, etc. The above code is quite self-explanatory ig
Adding More Functionalities to our Authentication System apart from basic things
So letās move on my adding functions like Email verification, password reset, etc. For that,Ā In the Authentication section, click on the templates tabĀ Or directly go to thisĀ
Email address verification
Now, letās work on all the 3 things on the sidebar. First, we have the Email address verification thing. Like below ā¬ļøā¬ļøā¬ļø
Now, Click on the edit button in and change the things you want. Like āsender nameā and āfromā settings. In the message section, you see this weird line right?
http://localhost:3000/UserActions?mode=action&oobCode=code
For all the user management actions such as updating a userās email address and resetting a userās password, we send an email to the userās email duh.Ā So, By default, user management emails link to the default action handler, which is a web page hosted at a URL in your projectās Firebase Hosting domain. Firebase adds several query parameters to your action handler URL when it generates user management emails. For example:
https://example.com/usermgmt?mode=resetPassword&oobCode=ABC123&apiKey=AIzaSy...&lang=fr
For more info, you can read about itĀ
https://firebase.google.com/docs/auth/custom-email-handler
So, letās change the default action handler. Itās not that difficult ;). In the bottom section, you would be able to see a text with āCustomize action URLā and there put the following value.
http://localhost:3000/UserActions
Donāt worry if you are confused right now, when we will start implementing these features, you will get more clear ;))
Password reset AND Email address change Settings
There is nothing more to do in these settings. Just change the text you want etc but idk we have nothing more left to do here.
OOF OOF, that whole section was a mouthful, It might look boring a bit but nvm we are finished and now we can close this site ā¤ļøā¤ļøš³
Complete UserAuthContext File with All Login Functions
Now letās complete our UserAuthContext file. This will be the complete file. Itās not that complicated ig, Just 1ā2 lines of code with some settings to pass and we have the functionality running
import React, { useContext, useState, useEffect } from "react";
import {
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
onAuthStateChanged,
signOut,
GoogleAuthProvider,
signInWithPopup,
sendPasswordResetEmail,
confirmPasswordReset,
sendSignInLinkToEmail,
isSignInWithEmailLink,
signInWithEmailLink,
} from "firebase/auth";
import { doc, setDoc } from "firebase/firestore";
import { db, auth } from "../Config/FirebaseConfig";
const AuthContext = React.createContext();
export const useAuth = () => {
const auth = useContext(AuthContext);
return { ...auth, isAuthenticated: auth.CurrentUser != null };
};
export function AuthProvider({ children }) {
const [CurrentUser, setCurrentUser] = useState();
const [loading, setloading] = useState(true);
useEffect(() => {
const unsuscribe = onAuthStateChanged(auth, (user) => {
console.log(user);
setCurrentUser(user);
setloading(false);
});
return unsuscribe;
}, []);
const SignupUser = (email, password, name) => {
return createUserWithEmailAndPassword(auth, email, password).then(
(resp) => {
if (resp.user) {
CreateFireStoreUser(
resp.user,
name,
"https://cdn-icons-png.flaticon.com/512/149/149071.png"
);
}
}
);
};
const CreateFireStoreUser = (user, name, profileImage) => {
const UsersRef = doc(db, "Users", user.uid);
setDoc(UsersRef, {
name: name,
profileImage: profileImage,
initials: name[0] + name[name.length - 1],
Suscribers: [],
}).then(() => {
console.log("added User");
});
};
const LogInUser = (email, password) => {
return signInWithEmailAndPassword(auth, email, password);
};
const SendEmailVerification = () => {
const actionCodeSettings = {
url: "http://localhost:3000", // Redirect to this url when we are succesfull
handleCodeInApp: true,
};
return sendSignInLinkToEmail(auth, CurrentUser.email, actionCodeSettings);
};
const VerifyEmailLink = () => {
if (isSignInWithEmailLink(auth, window.location.href)) {
return signInWithEmailLink(auth, CurrentUser.email);
}
};
const SignInWithGoogle = () => {
const provider = new GoogleAuthProvider();
return signInWithPopup(auth, provider);
};
const forgotPassword = (email) => {
return sendPasswordResetEmail(auth, email, {
url: "http://localhost:3000/login",
});
};
const ResetPassword = (oobcode, newPasword) => {
return confirmPasswordReset(auth, oobcode, newPasword);
};
const logout = () => {
return signOut(auth);
};
const value = {
CurrentUser,
SignupUser,
LogInUser,
logout,
SignInWithGoogle,
forgotPassword,
ResetPassword,
CreateFireStoreUser,
SendEmailVerification,
VerifyEmailLink,
};
return (
<AuthContext.Provider value={value}>
{!loading && children}
</AuthContext.Provider>
);
}
Annd with that, we have completed our Context API file too! Nice :000000. Well, the article went a bit long today but donāt worry we have some output :))
Now in the next part, we will complete the Authentication system with all the screens. We are moving slowly but we will soon be able to see some results. I bet.
I hope you like this part and I will be back with another part soon! Till then
Till then stay safe, stay healthy
Thank you
Also Published Here