Introduction
Good day everyone! Today we are gonna start working on a new tutorial series on firebase.
In this series we will use firebase and nextjs 13 to build a clone of instagram, complete with the following functionality:
- Google and email sign in (with Firebase auth)
- CRUD functionality for posts and comments (with Firebase firestore)
- Hosting of our own images and gifs (with Firebase storage)
- Simple automatic banning of undesired content (with Firebase functions)
I'll even throw in hosting in vercel (NextJs is easier to host in vercel than in firebase)
Hopefully this all sounds exiting, this first part of our project will focus on setting up firebase, and our NextJs project.
- Little shameful advertising time! I actually will upload this series in my own personal website over at daniel-armenta.com. I will post parts there first, so consider checking it out and letting me know when you inevitably find bugs in my website.
Create a NextJs 13 project
To begin, let's create a new project with NextJs version 13.
To do this, run the following command inside your projects directory:
npx create-next-app@latest --ts instagram-tutorial
For this project I will be using typescript, so I added the --ts flag, but I will also share the javascript code here for you to use if you don't like typescript, so feel free to remove that flag.
Running this command will give you the following output if you haven't installed create-next-app:
Need to install the following packages:
create-next-app@13.3.2
Ok to proceed? (y)
Go ahead and press enter and now you will be given a few options, I'll show what I set up, but if you have some different preference, feel free to change your answers.
- Would you like to use ESLint with this project? ... No / Yes
- Would you like to use Tailwind CSS with this project? ... No / Yes
- Would you like to use
src/
directory with this project? ... No / Yes - Would you like to use experimental
app/
directory with this project? ... No / Yes - What import alias would you like configured? ... @/*
Warning! keep in mind that if you decide not to use the experimental app directory, your project and mine will look very different
After running this command and waiting a bit, you should see a message like the following:
Success! Created instagram-tutorial at D:\Users\h8moss\projects\instagram-tutorial
Go ahead and open the project in your favorite code editor and run npm run dev
to start debugging on localhost:3000
Open localhost:3000 and you should see something like this:
Now over at our code editor, we can see our project looks like this:
The .next
, .vscode
and node_modules
folders can be ignored. We can also ignore .gitignore
, README.md
, next.env.d.ts
, package.json
and package-lock.json
The public
folder includes static files for our app, like the logo or a robots.txt
file if we wanted.
The next.config.js
file contains configuration for our nextJs project, we can leave it be for now.
tsconfig.json
has simple typescript configuration for the project.
Finally, the src
directory will contain all of our code. The app
directory inside it determines the routing of our app.
We can see there is a page.tsx
and a layout.tsx
at the root of our app, there is also a route.ts
at /api/hello
. If you are new to nextjs 13, I will explain what all of these routes are shortly.
Inside the app directory, there are special files identified by their names, we currently have the following:
- The
page.tsx
file, which defines a page inside of our app. - The
layout.tsx
file, which defines code that every child page will have. - The
route.ts
file which defines an API handler route.
There are also other special files we will come to know later down the tutorial series.
For now, the route.ts
file inside /api/hello folder means that localhost:3000/api/hello
works as an API directory, we don't actually need this behaviour, so let's remove the entire /api
folder.
We also have a layout.tsx
file at the root of our app folder, this means that every route will share the code inside this layout file. The layout file looks like this:
import './globals.css'
import { Inter } from 'next/font/google'
const inter = Inter({ subsets: ['latin'] })
export const metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
)
}
This file first imports the globals.css
file, which contains our general css.
Then imports and defines Inter
which is the font used in the example.
Next we export a metadata object, which has head
related information like the title and description.
It finally, exports a component, which just defines an html tag with a body and the {children} property, which will be replaced with the actual code of our pages.
All of this is pretty basic stuff, so we won't change much, let's just change the metadata object to align more with what we are trying to make:
export const metadata = {
title: "Instagram clone",
description:
"A simple website for a tutorial, showcasing the capabilities of Nextjs and firebase",
};
Let's also go over to globals.css
and replace all of the default styles with something much more simple:
* {
padding: 0;
margin: 0;
}
html,
body {
max-width: 100vw;
overflow-x: hidden;
}
a {
color: inherit;
}
If we need more global styles, we can add them later.
This is not a CSS tutorial, so the styles we will be using will not be explained and they will be very rudamentary, I will give you the styles but I won't explain them, so feel free to experiment with your own styles.
The next file we have to take a look at is the page.tsx
file.
This file, as it is in the root of our app directory, defines the root of our website, it currently has a lot of code for the website we saw earlier, so let's replace it with something far more simple:
const Root = () => {
return (
<div>
<h1>Hello world</h1>
<p>Welcome to NextJs 13</p>
</div>
);
};
export default Root;
We can also delete the page.module.css
file for now, as we don't have any page specific styles.
Do keep in mind we will probably create it again later, so you can just delete the contents if you want.
Setting up a firebase project
Now that we have a basic NextJs project, let's go ahead and create a firebase project.
To do this, I took the liberty of making a scribe document
If you can't see, or don't want to use the scribe, the actual steps are as follows:
- Go to the firebase console
- Sign in or create an account
- Click on "Add project"
- Give the project a name
- Select continue until asked about google analytics account
- Select default account.
- Select continue again
- Wait for the project to be created.
- Press continue
Now that we have a firebase project, we are gonna set up the following things:
- Authentication
- Database
- Storage
So first, over to the left there are some menus, under the build menu we will find the authentication
option, go ahead and click it.
Setting up authentication
You know what to do, let's go over to the authentication page:
Now that we are on the authentication page, let's click on the "get started" button, which after a while will take you to the following page:
This page has a list of all the different sign in options a user can have. There are 3 categories:
- Native providers: The most basic providers, like email and password or phone authentication
- Additional providers: Providers that use some different website to sign in, like twitter or google.
- Custom providers: These providers allow you to use some special features of authentication, but have different pricing, you can read more here
For our project, we only want the email/password provider and the google provider
Let's first register the email provider, which requires the least configuration of all, go ahead and click on the email/password
button.
You will see 2 options, the first enables normal email/password sign in, the second enables password-less sign in. We only want email/password sign in, so let's only enable that one
Now it is possible to sign in to our website using an email and a password, let's continue by activating google sign in, which requires a "public-facing name" and a "support email".
So go click on the new "add new provider" button and add the google provider:
With this, we now have activated the possibility of signing in with either google or a username and password.
Challenge
With the google and email sign in we have more than enough providers, but would you like to add a different provider into your app? You could try to add a facebook sign in option or a twitter sign in option, both of which require a developer account with either facebook or twitter, which I don't have by principle, but nothing is stopping you from making them.
Here are some resources:
- Firebase authentication docs
- Firebase facebook authentication tutorial
- Firebase twitter authentication tutorial
Setting up a database in firebase
Firebase also comes with two different databases we could use, the realtime database and the firestore database. We are gonna be using the firestore database for this project.
Go ahead and click on the firestore button on your build menu:
You should see a button to create a database, go ahead and click it, you will be asked 2 questions.
The first question asks about "production" vs "test" mode, this sets the rules for accessing the database, production mode defaults all operations to false, so you have to manually set rules while test mode sets them to true for a few days and changes them to false later.
We are gonna write our own rules later down the line, but for now, pick test mode.
The second question asks you where should the database be set up, for most projects you are gonna want either nam5 (US) or eur3 (Europe) depending on when you live. I live in Mexico, so I picked the US as that is closer.
We have now created a working database, from this page we can view and edit the database's values, we will come back to this page in the firestore chapter, but for now, let's setup the storage system.
Setting up storage
One last time, go over to the menu, this time click on storage:
You will be asked the same questions as when setting up firestore, but this time you won't be able to change the region as both firestore and storage must use the same region.
Go ahead and put the same values in.
With that, our firebase storage should be working, we could start uploading stuff to it right now.
Adding Firebase to our NextJS project
Now that we have created a firebase repository, we should try to add firebase to our NextJS project, to do that, let's install the firebase dependency:
npm install firebase
In order to use firebase, we need some information about our firebase project, this information is private and so we are gonna put it inside of a .env.local
file. NextJS automatically reads any .env.local
files in our repository and sets them as the keys of the process.env
object.
Note that, in reality, the data we are gonna store is not so sensitive that we need to use a .env.local
file to hide it. Still, it is a good idea to do so, just in case.
So create a .env.local
file at the root of the project And fill it with the following:
NEXT_PUBLIC_FIREBASE_API_KEY=...
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=...
NEXT_PUBLIC_FIREBASE_PROJECT_ID=...
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=...
NEXT_PUBLIC_FIREBASE_MESSAGE_SENDER_ID=...
NEXT_PUBLIC_FIREBASE_APP_ID=...
NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=...
Make sure to add the NEXT_PUBLIC
prefix, as it will allow us to read these variables from the client
Also remember to add the file into your .gitignore
file if you are using git. If you want, I recommend creating a .env.example
file for keeping example data to describe what the actual .env.local
file has.
I'll explain in a second where we can find all this information, but first, let's put this information to use in our project.
Inside any folder where you want to keep your utility code, create a firebase file to put all of our firebase SDK related code
Personally, I like to create a src/common/services/firebase
folder, inside of which I make a single file for each of the SDKs we are gonna use (for now only the main firebase SDK, but we will add more) and then a single index.ts
file that imports all of them and exports them, so we can import directly from the folder.
Inside this file, we are gonna initialize the firebase app
SDK, which will be required by all other firebase SDKs.
import { initializeApp } from 'firebase/app';
const firebaseConfig = {
};
const app = initializeApp(firebaseConfig);
export default app;
Now, the firebaseConfig
object is the one that will take all of our variables, so let's go ahead and fill our object:
const firebaseConfig = {
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID,
};
Great! Now, let's go over to the firebase console to get our data for our .env
file.
First, go over to the firebase console menu and click on "Project overview"
Here we can see information about our project, including all of the apps that use our firebase project.
We are gonna add a new web app, So click on the web simbol, from there, give your app a name.
You should now be able to see the data that we need to add to our .env
file
Go ahead and copy that information over to your .env
file, that should be enought to initialize firebase.
Conclusion
And we are done! I know that was a lot of setup to end up barely writing any code, but the good news is that we are done setting up and we can now focus on writing code.
Next part in the series will focus on using all of the auth setup we did to create a simple sign in page and display the username of whoever is signed in.
Top comments (0)