Skip to main content

4 posts tagged with "JavaScript"

View All Tags

Add ChatGPT to your portfolio

· 6 min read
Umut YILDIRIM
Fullstack Developer

ChatGPT and similar large language models (LLMs) are currently at the forefront of every developer's mind, emerging as the latest trend in 'Silicon Valley'. The hype is real, and the possibilities are endless. But how do you get started? In this article, I will show you how to create a simple chatbot using ChatGPT and Voiceflow. I will also show you how to add it to your portfolio using Docusaurus.

Let's understand the basics first

Before delving into the creation of a ChatGPT-based chatbot, it's essential to grasp the fundamental principles underlying ChatGPT. Developed by OpenAI, ChatGPT stands as a prominent example of a large language model (LLM), distinguished by its proficiency in producing text that closely resembles human writing. This capability stems from its design as a transformer model, a type of architecture that has significantly advanced the field of natural language processing (NLP).

ChatGPT trying its best

The core strength of ChatGPT lies in its extensive training on a diverse array of text sources. This comprehensive dataset equips the model with a broad understanding, enabling it to engage in and respond to a wide spectrum of topics with a natural, conversational tone.

ChatGPT Inaccurate

However, the reliance on pre-existing data also introduces a limitation. ChatGPT's knowledge is confined to its training material, meaning it lacks the ability to generate information beyond its training scope. This is where innovative technologies like Retrieval-Augmented Generation (RAG) play a pivotal role. RAG merges the transformer model's capabilities with a search engine's prowess. This combination allows ChatGPT to not only generate responses based on its internal knowledge but also to pull in and utilize relevant, up-to-date information from external sources, such as the internet or specialized vector databases. This enhancement significantly broadens the model's applicability and accuracy, making it a more dynamic tool in the realm of NLP.

ChatGPT Retrival

Let's build a chatbot

Now that we have a basic understanding of ChatGPT, let's build a chatbot using Voiceflow. Voiceflow is a no-code platform that allows you to create voice and chat-based applications. It is a great tool for beginners and experienced developers alike, as it provides a simple, intuitive interface that enables you to build a functional chatbot in a matter of minutes. It also offers 'Knowledge Base' integration, which is essential for our chatbot project.

Create a new assistant

First, create a new assistant by clicking on the 'Create Assistant' button on the top right corner of the screen. Then, name your chatbot and select the 'Chat' option and don't forget to select your preferred language. Finally, click on the 'Create Assistant' button to create your assistant.

Voiceflow Creator

Voiceflow Creator Filles

Congratulations! You have successfully created your first assistant. Now, let's move on to the next step and add some knowledge to your assistant.

Change response type to 'Knowledge Base'

Since we want a chatbot that anwsers questions based on your personal knowledge base, we need to change the response type to 'Knowledge Base'. To do that, click on the first block on 'AI response output' and select the 'Knowledge Base' option. Finally, click on the 'Save' button to save your changes.

Voiceflow Knowledge Base

Update

Voiceflow has changed the way your knowledge base is used. Instead of Retrieval method they are now using Agents to grap relavent information from your knowledge base. This is a great improvement and makes your chatbot more accurate.

Voiceflow Knowledge Base

Well now your chatbot is ready to answer questions but it doesn't have any knowledge yet. Let's add some knowledge to your assistant.

Add knowledge to your assistant

To add knowledge to your assistant you need to prepare text, PDF, DOCX or your existing website. After that, you need to upload it to Voiceflow. Once you have uploaded your knowledge, you can start adding it to your assistant.

Voiceflow Knowledge Base

To do that, click on the 'Add Knowledge' button on the top right corner of the screen. Then, select the 'Upload' option and upload your knowledge. Finally, click on the 'Add Knowledge' button to add your knowledge to your assistant.

Voiceflow Knowledge Base Filed

Congratulations! You have successfully added knowledge to your assistant. Now, let's move on to the next step and test your assistant.

Test your assistant

WOW in less then 10 minutes you have created your first chatbot. Now, let's test your assistant. To do that, click on the 'Run' button on the top right corner of the screen or simply press 'R' button on your keyboard. Then, click on the 'Run Test' button to start testing your assistant.

Voiceflow Chatbt Test First

Let's start asking some easy questions. For example, ask your chatbot 'Who is your name?' or 'What is your name's current employer?'. If you have added your personal information to your knowledge base, your chatbot should be able to answer your questions.

Voiceflow First Test

If you don't see any answers you are either missing some information in your knowledge base or you have not added your knowledge base to your assistant. If you have added your knowledge base to your assistant, you can check if you have added your knowledge base to your assistant by clicking on the 'Knowledge Base' button on the top right corner of the screen.

Add your chatbot to your portfolio

If your portfolio is HTML based, you can add your chatbot to your portfolio by adding the following code to your HTML file.

<script type="text/javascript">
(function (d, t) {
var v = d.createElement(t),
s = d.getElementsByTagName(t)[0];
v.onload = function () {
window.voiceflow.chat.load({
verify: {projectID: 'your project id'},
url: 'https://general-runtime.voiceflow.com',
versionID: 'production',
});
};
v.src = 'https://cdn.voiceflow.com/widget/bundle.mjs';
v.type = 'text/javascript';
s.parentNode.insertBefore(v, s);
})(document, 'script');
</script>

You can also costumize your chatbot by checking out integrations tab on Voiceflow.

Voiceflow Integrations

Add your chatbot to your Docuaurus portfolio

If your portfolio is based on Docuaurus, you can add your chatbot to your portfolio by following these steps.

Create a new file called voiceflow.js in your src/theme folder and add the following code to it.

import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';

if (ExecutionEnvironment.canUseDOM) {
(function (d, t) {
var v = d.createElement(t),
s = d.getElementsByTagName(t)[0];
v.onload = function () {
window.voiceflow.chat.load({
verify: {projectID: '64bad5417ef5eb00077b0c2d'},
url: 'https://general-runtime.voiceflow.com',
versionID: 'production',
});
};
v.src = 'https://cdn.voiceflow.com/widget/bundle.mjs';
v.type = 'text/javascript';
s.parentNode.insertBefore(v, s);
})(document, 'script');
}

Then, add the following code to your docusaurus.config.js file.

  clientModules: [require.resolve('./src/theme/voiceflow.js')],

and you are done. Now, you can start your local server by running yarn start and test your chatbot.

Voiceflow Docusaurus

Conclusion

This guide demonstrated how to enhance your tech portfolio by integrating ChatGPT into a chatbot project, using Voiceflow and Docusaurus. It's a testament to the ease of using advanced AI in modern web development, showcasing your skills in navigating emerging technologies. This project is not just a technical achievement, but a step towards future innovations in AI. Keep exploring and embracing new tech frontiers!

Ruby Active Record Built-In Methods Beginner Guide

· 6 min read
Umut YILDIRIM
Fullstack Developer

It doesn’t matter if you are a beginner or a seasoned developer. From time to time, you need to look up certain programming language documentation to help you navigate through specific information to build up your application which then solves a definite task or problem. However, this skill is especially important for beginner developers since beginner developers, like myself, don’t have many experiences in using built-in methods nor understanding how to implement the methods and the keywords to look for. For example, some methods require certain numbers of parameters, or even just simply land on the right page on the documentation.

The purpose of this article is to assist and guide other beginner developers on where to start when they read and refer to Ruby built-in methods in Ruby on Rails Guide. This time I am going to focus on introducing the Models section which is related to setting up your backend database from scratch. Ruby on Rails Docs For Active Record

Before diving into the Models, let’s take a look at what Active Record is first. We know that Rails contains seven Ruby gems, which work harmoniously together, and Active Record is one of them and taking care of all the database stuff, also known as an “ORM”. ORM stands for Object-Relational-Mapping and it means Active Record stores data in a database table kind of structure using rows and columns and the data can be modified or retrieved by writing SQL statements. Moreover, Active Record allows you to interact with that data as if it’s a normal Ruby object.

What is Active Record?

Active Record Active Record is the M in MVC — the model — which is the layer of the system responsible for representing business data and logic. Active Record facilitates the creation and use of business objects whose data requires persistent storage to a database. It is an implementation of the Active Record pattern which itself is a description of an Object Relational Mapping system.

What is UML?

UML UML, short for Unified Modeling Language, is a standardized modeling language consisting of an integrated set of diagrams, developed to help system and software developers for specifying, visualizing, constructing, and documenting the artifacts of software systems, as well as for business modeling and other non-software systems. The UML represents a collection of best engineering practices that have proven successful in the modeling of large and complex systems. The UML is a very important part of developing object oriented software and the software development process. The UML uses mostly graphical notations to express the design of software projects. Using the UML helps project teams communicate, explore potential designs, and validate the architectural design of the software. In this article, we will give you detailed ideas about what is UML, the history of UML and a description of each UML diagram type, along with UML examples.

All About Active Record Migrations

Now you understand Models section is related to setting up your backend database but still where should you start looking? First thing first, we need to define our schema so our apps know what type of data they are receiving and storing. This is the time you can refer to the Active Record Migrations page to review some migration definitions that are supported by the built-in change method, as below: (To see a full list, you can visit here)

  • add_column
  • add_foreign_key
  • create_join_table
  • create_table
  • drop_join_table
  • drop_table (must supply a block)
  • remove_column (must supply a type)
  • remove_foreign_key (must supply a second table)
  • rename_column
  • rename_index
  • rename_table

After all, we are humans and we make mistakes, or after a while, you need to change the database table, such as adding or removing columns, based on the new business decision and your supervisor needs you to make the changes. You may or may not remember how to make the change so it’s the place you can find the information you need.

All About Active Record Associations

Now after we have the ideas of how we would like to define the schema, we also need to think about the relationship between each database table. For example, we have a table to store all the books and another table contains all the book authors. Should we use has_many and belongs_to types of association or has_and_belongs_to_many association? Since there may be a case that one book has more than one author. When you come across association-related questions that you can search for the Active Record Associations page.

All About Active Record Query Interface

Eventually, you would like to retrieve the data from the database after you have finished all the database creation and it’s the moment you would like to spend your time studying Active Record Query Interface page which covers different ways that you can interact with your data using Active Record. Personally, Active Record Query Interface is the one that I visit the most, and easily get confused about which finder method should I use and how many arguments that I can pass into the method.

Below is a list of often used finder methods:

  • find
  • extending
  • from
  • group
  • having
  • includes
  • joins
  • lock
  • none
  • order
  • reorder
  • reselect
  • reverse_order
  • select
  • where

For retrieving a single object, below are the methods you can consider:

  • find
  • take
  • first
  • last
  • find_by

For retrieving multiple objects in batches, below are the methods you can consider:

  • find_each
  • find_in_batches
  • first
  • last
  • find_by

Although, some of the finder methods you may think their functions look similar at first, you should always double-check what are their expected return result and decide which method you should use. For example, how do you decide when to use find_by, where or find if you want to search for data from the database?

Use find_by , if you’re expecting a single record or nil as a return Use where , if you’re expecting an ActiveRecord::Relation object as a return Use find_by , if you’re expecting a single record (by its primary column, usually id ) as a return Key Takeaway

Knowing and understanding where you get stuck is the key before you jump right into the Ruby on Rails Guide and start looking for answers. Ask yourself this question first — At what step am I having a problem now? Is it migration, association, or retrieving the data (query interface)?

Resources

Handling user authentication with Firebase in your React apps

· 15 min read
Umut YILDIRIM
Fullstack Developer

Header Image

Nowadays, security is very important on websites and apps. That’s mainly to ensure that private data is not leaked to the public and someone doesn’t do actions on your behalf.

Today, we are going to use Firebase, which is a BaaS that helps us with various services such as database authentication and cloud storage. We are going to see how we can use the authentication service in Firebase to secure our React app.

Requirements for authenticating with Firebase in React

  • Node.js installed
  • Code editor — I prefer Visual Studio Code
  • Google account — we need this to use Firebase
  • Basic knowledge of React — I won’t recommend this tutorial for complete beginners in React

Setting up Firebase

Before we dive into React and start coding some good stuff, we need to set up our own Firebase project through the Firebase Console. To get started, navigate your browser to Firebase Console. Make sure you are logged into your Google account.

Now, click on Add project and you should be presented with the following screen:

Once you’ve given it a sweet name, click on Continue and you should be prompted for an option to enable Google Analytics. We don’t need Google Analytics for this tutorial, but turning it on won’t do harm, so go ahead and turn it on if you want.

Once you’ve completed all the steps, you should be presented with the dashboard, which looks something like this:

Firebase Project Created First, let’s set up authentication. Click on Authentication on the sidebar and click on Get Started to enable the module. Now you will be presented with various authentication options:

Firebase Auth Page First click on Email/Password, enable it, and save it:

Email Password Options Firebase Now press on Google:

Google Options Firebase Press enable, select a project support email address, and click on Save to activate Google Authentication for our app.

Now, let’s set up the database we are going to use for our project, which is Cloud Firestore. Click on Cloud Firestore on the sidebar and click on Create Database. You should be presented with the following dialog:

Cloud Firestore Create Database Remember to select Start in test mode. We are using test mode because we are not dealing with production-level applications in this tutorial. Production mode databases require a configuration of security rules, which is out of the scope of this tutorial.

Click Next. Select the region. I’ll leave it to the default, and then press Enable. This should completely set up your Cloud Firestore database.

Creating and setting up a React app

Navigate to a safe folder and type the following command in the terminal to create a new React app:

npx create-react-app appname

Remember to replace appname with a name of your choice. The name doesn’t really affect how the tutorial works. Once the React app is successfully created, type the command to install a few npm packages we will need throughout the project:

npm install firebase react-router-dom react-firebase-hooks

Here, we are installing firebase to communicate with Firebase services, and we are also installing react-router-dom to handle the routing of the application. We use react-firebase-hooks to manage the authentication state of the user.

Type the following command to run your React app:

cd appname && npm start

This should fire up your browser and you should see the following screen: React App Beginning Setup Firebase Now, let’s do some cleanup so that we can continue with coding. Delete the following files from the src folder: App.test.js, logo.svg, and setupTests.js. Once you delete these files, delete all the contents of App.css and you will see an error on the React app. Don’t worry; just remove the logo imports in App.js and empty the div so that your App.js looks like this:

import './App.css';
function App() {
return (
<div className="app">

</div>
);
}
export default App;

Integrating Firebase into our React app

Go to your Firebase Console dashboard, click on Project Settings, scroll down, and you should see something like this:

Project Settings No App Firebase Click on the third icon to configure our Firebase project for the web. Enter the app name and click on Continue. Go back to the project settings and you should now see a config like this:

Web Config Firebase Console Copy the config. Create a new file in the src folder named firebase.js. Let’s first import firebase modules, since Firebase uses modular usage in v9:

import { initializeApp } from "firebase/app";
​​import {
​​ GoogleAuthProvider,
​​ getAuth,
​​ signInWithPopup,
​​ signInWithEmailAndPassword,
​​ createUserWithEmailAndPassword,
​​ sendPasswordResetEmail,
​​ signOut,
​​} from "firebase/auth";
​​import {
​​ getFirestore,
​​ query,
​​ getDocs,
​​ collection,
​​ where,
​​ addDoc,
​​} from "firebase/firestore";

Now paste in the config we just copied. Let’s initialize our app and services so that we can use Firebase throughout our app:

const app = ​​initializeApp(firebaseConfig);
​​const auth = getAuth(app);
​​const db = getFirestore(app);

This will use our config to recognize the project and initialize authentication and database modules.

We will be creating all important authentication-related functions in firebase.js itself. So first look at the Google Authentication function:

const googleProvider = new GoogleAuthProvider();
const signInWithGoogle = async () => {
try {
const res = await signInWithPopup(auth, googleProvider);
const user = res.user;
const q = query(collection(db, "users"), where("uid", "==", user.uid));
const docs = await getDocs(q);
if (docs.docs.length === 0) {
await addDoc(collection(db, "users"), {
uid: user.uid,
name: user.displayName,
authProvider: "google",
email: user.email,
});
}
} catch (err) {
console.error(err);
alert(err.message);
}
};

In the above code block, we are using a try…catch block along with async functions so that we can handle errors easily and avoid callbacks as much as possible.

First, we are attempting to log in using the GoogleAuthProvider Firebase provides us. If the authentication fails, the flow is sent to the catch block.

Then we are querying the database to check if this user is registered in our database with the user uid. And if there is no user with the uid, which also means that the user is new to our app, we make a new record in our database with additional data for future reference.

Now let’s make a function for signing in using an email and password:

const logInWithEmailAndPassword = async (email, password) => {
try {
await signInWithEmailAndPassword(auth, email, password);
} catch (err) {
console.error(err);
alert(err.message);
}
};

This code is very simple. Since we know that the user is already registered with us, we don’t need to check the database. We can proceed with the authentication right away. We just pass in the email and password to signInWithEmailAndPassword functions, which is provided to us by Firebase.

Now, let’s create a function for registering a user with an email and password:

const registerWithEmailAndPassword = async (name, email, password) => {
try {
const res = await createUserWithEmailAndPassword(auth, email, password);
const user = res.user;
await addDoc(collection(db, "users"), {
uid: user.uid,
name,
authProvider: "local",
email,
});
} catch (err) {
console.error(err);
alert(err.message);
}
};

Since we know that the user is new to our app, we create a record for the user without checking if there is one existing in our database. It’s similar to the approach we used in Google Authentication but without checks.

Create a function that will send a password reset link to an email address:

const sendPasswordReset = async (email) => {
try {
await sendPasswordResetEmail(auth, email);
alert("Password reset link sent!");
} catch (err) {
console.error(err);
alert(err.message);
}
};

This code is simple. We are just passing in the email in the sendPasswordResetEmail function provided by Firebase. The password reset email will be sent by Firebase.

And finally, the logout function:

const logout = () => {
signOut(auth);
};

Nothing much here, just firing up the signOut function from Firebase, and Firebase will do its magic and log out the user for us.

Finally we export all the functions, and here’s how your firebase.js should finally look:

import { initializeApp } from "firebase/app";
import {
GoogleAuthProvider,
getAuth,
signInWithPopup,
signInWithEmailAndPassword,
createUserWithEmailAndPassword,
sendPasswordResetEmail,
signOut,
} from "firebase/auth";
import {
getFirestore,
query,
getDocs,
collection,
where,
addDoc,
} from "firebase/firestore";
const firebaseConfig = {
apiKey: "AIzaSyDIXJ5YT7hoNbBFqK3TBcV41-TzIO-7n7w",
authDomain: "fir-auth-6edd8.firebaseapp.com",
projectId: "fir-auth-6edd8",
storageBucket: "fir-auth-6edd8.appspot.com",
messagingSenderId: "904760319835",
appId: "1:904760319835:web:44fd0d957f114b4e51447e",
measurementId: "G-Q4TYKH9GG7",
};
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const db = getFirestore(app);
const googleProvider = new GoogleAuthProvider();
const signInWithGoogle = async () => {
try {
const res = await signInWithPopup(auth, googleProvider);
const user = res.user;
const q = query(collection(db, "users"), where("uid", "==", user.uid));
const docs = await getDocs(q);
if (docs.docs.length === 0) {
await addDoc(collection(db, "users"), {
uid: user.uid,
name: user.displayName,
authProvider: "google",
email: user.email,
});
}
} catch (err) {
console.error(err);
alert(err.message);
}
};
const logInWithEmailAndPassword = async (email, password) => {
try {
await signInWithEmailAndPassword(auth, email, password);
} catch (err) {
console.error(err);
alert(err.message);
}
};
const registerWithEmailAndPassword = async (name, email, password) => {
try {
const res = await createUserWithEmailAndPassword(auth, email, password);
const user = res.user;
await addDoc(collection(db, "users"), {
uid: user.uid,
name,
authProvider: "local",
email,
});
} catch (err) {
console.error(err);
alert(err.message);
}
};
const sendPasswordReset = async (email) => {
try {
await sendPasswordResetEmail(auth, email);
alert("Password reset link sent!");
} catch (err) {
console.error(err);
alert(err.message);
}
};
const logout = () => {
signOut(auth);
};
export {
auth,
db,
signInWithGoogle,
logInWithEmailAndPassword,
registerWithEmailAndPassword,
sendPasswordReset,
logout,
};

Next, let’s work on the actual functionality.

Creating the login page

Create two new files to create a new component, Login.js and Login.css. I highly recommend installing ES7 snippets in Visual Studio Code so that you can just start typing rfce and press Enter to create a component boilerplate.

Now, let’s assign this component to a route. To do that, we need to configure React Router. Go to App.js and import the following:

import { BrowserRouter as Router, Route, Routes } from "react-router-dom";

Then, in the JSX part of App.js, add the following configuration to enable routing for our app:

<div className="app">
<Router>
<Switch>
<Route exact path="/" component={Login} />
</Switch>
</Router>
</div>

Remember to import the Login component on the top!

Go to Login.css and add the following styles. We won’t be focusing on styling much, so here are the styles for you to use:

.login {
height: 100vh;
width: 100vw;
display: flex;
align-items: center;
justify-content: center;
}
.login__container {
display: flex;
flex-direction: column;
text-align: center;
background-color: #dcdcdc;
padding: 30px;
}
.login__textBox {
padding: 10px;
font-size: 18px;
margin-bottom: 10px;
}
.login__btn {
padding: 10px;
font-size: 18px;
margin-bottom: 10px;
border: none;
color: white;
background-color: black;
}
.login__google {
background-color: #4285f4;
}
.login div {
margin-top: 7px;
}

Go to Login.js, and let’s look at how our login functionality works:

import React, { useEffect, useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import { auth, signInWithEmailAndPassword, signInWithGoogle } from "./firebase";
import { useAuthState } from "react-firebase-hooks/auth";
import "./Login.css";
function Login() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [user, loading, error] = useAuthState(auth);
const navigate = useNavigate();
useEffect(() => {
if (loading) {
// maybe trigger a loading screen
return;
}
if (user) navigate("/dashboard");
}, [user, loading]);
return (
<div className="login">
<div className="login__container">
<input
type="text"
className="login__textBox"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="E-mail Address"
/>
<input
type="password"
className="login__textBox"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Password"
/>
<button
className="login__btn"
onClick={() => signInWithEmailAndPassword(email, password)}
>
Login
</button>
<button className="login__btn login__google" onClick={signInWithGoogle}>
Login with Google
</button>
<div>
<Link to="/reset">Forgot Password</Link>
</div>
<div>
Don't have an account? <Link to="/register">Register</Link> now.
</div>
</div>
</div>
);
}
export default Login;

The above code might look long and hard to understand, but it’s really not. We have already covered the main authentication parts and now we are just implementing them in our layouts.

Here’s what’s happening in the above code block. We are using the functions we made in firebase.js for authentication. We are also using react-firebase-hooks along with useEffect to track the authentication state of the user. So, if the user gets authenticated, the user will automatically get redirected to the dashboard, which we are yet to make.

Here’s what you’ll see on your screen:

Basic Login Page React Firebase Create a new component called Register to handle user registrations. Here are the styles for Register.css:

.register {
height: 100vh;
width: 100vw;
display: flex;
align-items: center;
justify-content: center;
}
.register__container {
display: flex;
flex-direction: column;
text-align: center;
background-color: #dcdcdc;
padding: 30px;
}
.register__textBox {
padding: 10px;
font-size: 18px;
margin-bottom: 10px;
}
.register__btn {
padding: 10px;
font-size: 18px;
margin-bottom: 10px;
border: none;
color: white;
background-color: black;
}
.register__google {
background-color: #4285f4;
}
.register div {
margin-top: 7px;
}

After that, let’s look at how the register functionality is implemented in the layout. Use this layout in Register.js:

import React, { useEffect, useState } from "react";
import { useAuthState } from "react-firebase-hooks/auth";
import { Link, useHistory } from "react-router-dom";
import {
auth,
registerWithEmailAndPassword,
signInWithGoogle,
} from "./firebase";
import "./Register.css";
function Register() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [name, setName] = useState("");
const [user, loading, error] = useAuthState(auth);
const history = useHistory();
const register = () => {
if (!name) alert("Please enter name");
registerWithEmailAndPassword(name, email, password);
};
useEffect(() => {
if (loading) return;
if (user) history.replace("/dashboard");
}, [user, loading]);
return (
<div className="register">
<div className="register__container">
<input
type="text"
className="register__textBox"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Full Name"
/>
<input
type="text"
className="register__textBox"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="E-mail Address"
/>
<input
type="password"
className="register__textBox"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Password"
/>
<button className="register__btn" onClick={register}>
Register
</button>
<button
className="register__btn register__google"
onClick={signInWithGoogle}
>
Register with Google
</button>
<div>
Already have an account? <Link to="/">Login</Link> now.
</div>
</div>
</div>
);
}
export default Register;

Here, we are using similar approach as we used in the Login component. We are just using the functions we previously created in firebase.js. Again, here we are using useEffect along with react-firebase-hooks to keep track of user authentication status.

Let’s look at resetting passwords. Create a new component called Reset, and here’s the styling for Reset.css:

.reset {
height: 100vh;
width: 100vw;
display: flex;
align-items: center;
justify-content: center;
}
.reset__container {
display: flex;
flex-direction: column;
text-align: center;
background-color: #dcdcdc;
padding: 30px;
}
.reset__textBox {
padding: 10px;
font-size: 18px;
margin-bottom: 10px;
}
.reset__btn {
padding: 10px;
font-size: 18px;
margin-bottom: 10px;
border: none;
color: white;
background-color: black;
}
.reset div {
margin-top: 7px;
}

This is the layout for Reset.js:

import React, { useEffect, useState } from "react";
import { useAuthState } from "react-firebase-hooks/auth";
import { useNavigate } from "react-router-dom";
import { Link } from "react-router-dom";
import { auth, sendPasswordResetEmail } from "./firebase";
import "./Reset.css";
function Reset() {
const [email, setEmail] = useState("");
const [user, loading, error] = useAuthState(auth);
const navigate = useNavigate();
useEffect(() => {
if (loading) return;
if (user) navigate("/dashboard");
}, [user, loading]);
return (
<div className="reset">
<div className="reset__container">
<input
type="text"
className="reset__textBox"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="E-mail Address"
/>
<button
className="reset__btn"
onClick={() => sendPasswordResetEmail(email)}
>
Send password reset email
</button>
<div>
Don't have an account? <Link to="/register">Register</Link> now.
</div>
</div>
</div>
);
}
export default Reset;

This is similar to what we did for the Login and Register components. We are simply using the functions we created earlier.

Now, let’s focus on the dashboard. Create a new component called Dashboard, and here’s the styling for Dashboard.css:

.dashboard {
height: 100vh;
width: 100vw;
display: flex;
align-items: center;
justify-content: center;
}
.dashboard__container {
display: flex;
flex-direction: column;
text-align: center;
background-color: #dcdcdc;
padding: 30px;
}
.dashboard__btn {
padding: 10px;
font-size: 18px;
margin-top: 10px;
border: none;
color: white;
background-color: black;
}
.dashboard div {
margin-top: 7px;
}

And here’s the layout for Dashboard.js:

import React, { useEffect, useState } from "react";
import { useAuthState } from "react-firebase-hooks/auth";
import { useNavigate } from "react-router-dom";
import "./Dashboard.css";
import { auth, db, logout } from "./firebase";
import { query, collection, getDocs, where } from "firebase/firestore";
function Dashboard() {
const [user, loading, error] = useAuthState(auth);
const [name, setName] = useState("");
const navigate = useNavigate();
const fetchUserName = async () => {
try {
const q = query(collection(db, "users"), where("uid", "==", user?.uid));
const doc = await getDocs(q);
const data = doc.docs[0].data();
setName(data.name);
} catch (err) {
console.error(err);
alert("An error occured while fetching user data");
}
};
useEffect(() => {
if (loading) return;
if (!user) return navigate("/");
fetchUserName();
}, [user, loading]);
return (
<div className="dashboard">
<div className="dashboard__container">
Logged in as
<div>{name}</div>
<div>{user?.email}</div>
<button className="dashboard__btn" onClick={logout}>
Logout
</button>
</div>
</div>
);
}
export default Dashboard;

Unlike the other components, there’s something else we are doing here. We are checking the authentication state. If the user is not authenticated, we redirect the user to the login page.

We are also fetching our database and retrieving the name of the user based on the uid of the user. Finally, we are rendering out everything on the screen.

Lastly, let’s add everything to the router. Your App.js should look like this:

import "./App.css";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import Login from "./Login";
import Register from "./Register";
import Reset from "./Reset";
import Dashboard from "./Dashboard";
function App() {
return (
<div className="app">
<Router>
<Routes>
<Route exact path="/" element={<Login />} />
<Route exact path="/register" element={<Register />} />
<Route exact path="/reset" element={<Reset />} />
<Route exact path="/dashboard" element={<Dashboard />} />
</Routes>
</Router>
</div>
);
}
export default App;

The app is fully functional!

What's next?

Once you’re done with this build, I want you to play around with this. Try adding Facebook authentication next. What about GitHub authentication? I’d say keep experimenting with the code because that’s how you practice and learn things. If you just keep copying the code, you won’t understand the fundamentals of Firebase.

How to create your own backend API

· 5 min read
Umut YILDIRIM
Fullstack Developer

Hi there! I'm a new developer and I'm trying to create my own backend API for our project called Florida Man Stories. Firebase Functions is a cloud-hosted backend service that allows you to write serverless code in JavaScript. Florida Man project is about collecting every single news, that either includes 'Florida' or 'Florida Man'. This way users in Florida or people who want to get their crazy Florida news can access news much easily.

But why are we using Firebase Functions for this? There are couple of reason;

  1. This project could attract more people then a single computer can handle. I mean my serverless function code can scale to hundreds of servers. If there are thousands of people requesting same function, Firebase Functions will handle it.
  2. Firebase Functions is a cloud-hosted backend service that allows you to write serverless code in JavaScript or TyoeScript. So if you want to create your own backend API using JavaScript, you can use Firebase Functions.
  3. You only pay for the amount of time spend on your function. You don't need to pay for hourly instances, you don't use.
  4. Firebase automatically distributes your functions to the best available regions. This way you don't need to worry about which region to use.

So let's get started on how to create your own backend API.

Step 1: Create a Firebase project

Go to you Firebase console and click 'Add Project'. Create Firebase Project

You will be asked to enter a name for your project. Enter a name for your project and click 'Create'. If you want to add Google Analytics to your project, switch on the Google Analytics option and click 'Continue'. If you selected the Google Analytics option, you will be asked to choose a Google Analytics account. Choose a Google Analytics account and click 'Create'. If you are seeing welcome page after creating a new project, it means you have successfully created a new Firebase project.

Step 2: Upgrade Project to Enable Functions

Unfortunately, you have to upgrade your project to enable Firebase Functions. Click 'Upgrade Project' and create a budget. Create Billing Budget After creating a budget, click 'Purchase' to activate your plan. Purchase Plan Now you can enable Firebase Functions by clicking 'Get Started'. You will be given an npm package install command.

npm install -g firebase-tools

Copy the code above and run it in your terminal. If you encounter any error, try adding 'sudo' in front of the command and run it again. If you no longer see any error, you have successfully installed Firebase CLI. Now we can setup our project. Change your directory to the root of your project and run the following command.

firebase init

You will be asked to sign in to your Google account. Sign in and click 'Continue'. After signing in, you need to run the following command to setup your project. If you didn't signed in you need to use the command below.

firebase login

After signing in, you will need to initialize your project. You can initialize your project by running the following command.

firebase init

Firebase Init To enable Firebase Functions, you need to toogle on the 'Functions' option and press enter to finish your setup. Now you will see a few options. You need to select 'Use existing projects' and select your project with space and press enter key to select your project. Select Your Project After selecting your project, you will see a list of available languges. Since we will be using JavaScript, you need to select 'JavaScript' and press enter key to select JavaScript. After that selection you need to type 'n' to skip testing and type 'y' to install dependencies. Now you have successfully initialized your project and there should be a new folder called 'functions'. Firebase Initialization Complete

Step 3: Create a Function

After completing the setup, your project folder should look like this. Firebase Project Folder Now you can start editing your functions in Visual Studio Code. Open VSCode inside your projects root folder. This how your VSCode look like. VSCode Now you can start editing your functions. Open the file 'index.js' inside 'functions' folder and start editing. You need to uncomment the following code.

exports.helloWorld = functions.https.onRequest((request, response) => {
functions.logger.info("Hello logs!", {structuredData: true});
response.send("Hello from Firebase!");
});

Firebase Functions Index Uncommented

Step 4: Deploy Your Functions

Now you can deploy your functions. Open the terminal inside your VSCode and type the following command.

firebase deploy

After waiting for a few minute, you will see a message saying '✔ Deploy complete!'. Firebase Functions Deploy Complete Now let's go back to Firebase Console and click 'Finish' button to see your deployed functions. Firebase Console Functions Deployed

Step 5: Test Your Functions

Now you can test your functions by hovering over url under 'Trigger' table. Firebase Functions Hover Copy the URL and paste it in your browser. You should see the message 'Hello from Firebase!'. Firebase Function Deployed Web Congratulations! You have successfully created your own backend API and deployed it to Firebase. Now you can access your backend API from anywhere in the world. With this tutorial, you have learned how to create your own backend API using Firebase Functions. You can also create CRON jobs in Firebase using Google Cloud Scheduler.