Skip to content

Commit d705829

Browse files
committed
Nextjs + Firebase + Material UI Study
1 parent 720891e commit d705829

File tree

22 files changed

+8871
-1
lines changed

22 files changed

+8871
-1
lines changed

.env.example

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
FIREBASE_API_KEY=
2+
FIREBASE_AUTH_DOMAIN=
3+
FIREBASE_DATABASE_URL=
4+
FIREBASE_PROJECT_ID=
5+
FIREBASE_STORAGE_BUCKET=
6+
FIREBASE_MESSAGING_SENDER_ID=
7+
FIREBASE_APP_ID=

.eslintignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Directories
2+
3+
.next/
4+
build/
5+
dist/
6+
node_modules/
7+
8+
# Files
9+
10+
.DS_Store
11+
.env

.eslintrc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"extends": "airbnb",
3+
"parser": "babel-eslint",
4+
"globals": {
5+
"React": "writable",
6+
"window": true,
7+
"document": true,
8+
"webkit": true
9+
},
10+
"rules": {
11+
"react/jsx-filename-extension": "off",
12+
"react/prop-types": "off",
13+
"react/jsx-props-no-spreading": "off"
14+
}
15+
}

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Directories
2+
3+
.next/
4+
build/
5+
dist/
6+
node_modules/
7+
8+
# Files
9+
10+
.DS_Store
11+
.env

README.md

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,61 @@
11
# nextjs-firebase-materialui-study
2-
Nextjs + Firebase + Material UI Study
2+
3+
This is a simple set up for Firebase for client side applications.
4+
5+
The firebase app is initialized in `firebase/clientApp.js`, to use you just have to import it anywhere in the app
6+
7+
The React Context API is used to provide user state.
8+
9+
### Configuration
10+
11+
- [Create a Firebase project](https://console.firebase.google.com/u/0/) and add a new app to it.
12+
13+
- 🔑 Firebase Authentication
14+
15+
<img src="./public/firebase/firebase-01.jpg">
16+
17+
- 👨 Firebase Databse (`users`)
18+
19+
<img src="./public/firebase/firebase-02.jpg">
20+
21+
- 📄 Firebase Database (`database`)
22+
23+
<img src="./public/firebase/firebase-03.jpg">
24+
25+
- ⚙️ Firebase Database Rules
26+
27+
<img src="./public/firebase/firebase-04.jpg">
28+
29+
- Create a `.env` file and copy the contents of `.env.example` into it.
30+
31+
```bash
32+
cp .env.example .env
33+
```
34+
35+
- Set each variable on `.env` with your Firebase Configuration (found in "Project settings").
36+
37+
- Install it and run the application
38+
39+
```bash
40+
npm install
41+
npm run dev
42+
43+
# or
44+
45+
yarn
46+
yarn dev
47+
```
48+
49+
### Notes:
50+
51+
If you will use [Vercel](https://vercel.com/), keys will be coming from Vercel Secret keys.
52+
53+
```
54+
"@firebase-api-key"
55+
"@firebase-auth-domain"
56+
"@firebase-database-url"
57+
"@firebase-project-id"
58+
"@firebase-storage-bucket"
59+
"@firebase-messaging-sender-id"
60+
"@firebase-app-id"
61+
```

components/AppBar/AppBar.js

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import { useState } from 'react';
2+
import { makeStyles } from '@material-ui/core/styles';
3+
import AppBar from '@material-ui/core/AppBar';
4+
import Toolbar from '@material-ui/core/Toolbar';
5+
import Typography from '@material-ui/core/Typography';
6+
import IconButton from '@material-ui/core/IconButton';
7+
import NoteAddIcon from '@material-ui/icons/NoteAdd';
8+
import AccountCircle from '@material-ui/icons/AccountCircle';
9+
import MenuItem from '@material-ui/core/MenuItem';
10+
import Menu from '@material-ui/core/Menu';
11+
import Modal from '@material-ui/core/Modal';
12+
import SignIn from '../SignIn/SignIn';
13+
import Document from '../Document/Document';
14+
import firebase from '../../firebase/clientApp';
15+
import { useUser } from '../../firebase/userContext';
16+
17+
const useStyles = makeStyles(() => ({
18+
appbar: {
19+
flexGrow: 1,
20+
},
21+
title: {
22+
flexGrow: 1,
23+
},
24+
modal: {
25+
display: 'flex',
26+
alignItems: 'center',
27+
justifyContent: 'center',
28+
},
29+
}));
30+
31+
export default () => {
32+
const classes = useStyles();
33+
const { user } = useUser();
34+
const [anchorEl, setAnchorEl] = useState(null);
35+
const [activeModal, setActiveModal] = useState(null);
36+
37+
// menu
38+
const handleAccountMenu = (event) => {
39+
setAnchorEl(event.currentTarget);
40+
};
41+
const handleAccountMenuClose = () => {
42+
setAnchorEl(null);
43+
};
44+
const handleSignIn = () => {
45+
setAnchorEl(null);
46+
setActiveModal('signIn');
47+
};
48+
const handleSignOut = () => {
49+
firebase.auth().signOut();
50+
setAnchorEl(null);
51+
};
52+
const handleNewDocument = () => {
53+
setActiveModal('newDocument');
54+
};
55+
56+
// modal
57+
const handleModalClose = () => {
58+
setActiveModal(null);
59+
};
60+
61+
return (
62+
<div className={classes.appbar}>
63+
64+
{/* Appbar */}
65+
<AppBar position="static">
66+
<Toolbar>
67+
<Typography variant="h6" className={classes.title}>
68+
{user ? `${user.firstName} ${user.lastName}` : 'Nextjs + Firebase + Material UI Study' }
69+
</Typography>
70+
<div>
71+
{user && (
72+
<IconButton
73+
aria-label="add document"
74+
onClick={handleNewDocument}
75+
color="inherit"
76+
>
77+
<NoteAddIcon />
78+
</IconButton>
79+
)}
80+
<IconButton
81+
aria-label="account"
82+
aria-controls="menu-appbar"
83+
aria-haspopup="true"
84+
onClick={handleAccountMenu}
85+
color="inherit"
86+
>
87+
<AccountCircle />
88+
</IconButton>
89+
<Menu
90+
id="menu-appbar"
91+
anchorEl={anchorEl}
92+
anchorOrigin={{
93+
vertical: 'top',
94+
horizontal: 'right',
95+
}}
96+
keepMounted
97+
transformOrigin={{
98+
vertical: 'top',
99+
horizontal: 'right',
100+
}}
101+
open={Boolean(anchorEl)}
102+
onClose={handleAccountMenuClose}
103+
>
104+
{!user && <MenuItem onClick={handleSignIn}>Sign In</MenuItem>}
105+
{user && <MenuItem onClick={handleSignOut}>Sign Out</MenuItem>}
106+
</Menu>
107+
</div>
108+
</Toolbar>
109+
</AppBar>
110+
111+
{/* Modal */}
112+
{activeModal && (
113+
<Modal
114+
className={classes.modal}
115+
open={Boolean(activeModal)}
116+
onClose={handleModalClose}
117+
aria-labelledby="modal title"
118+
aria-describedby="modal description"
119+
>
120+
<>
121+
{activeModal === 'signIn' && <SignIn setActiveModal={setActiveModal} />}
122+
{activeModal === 'newDocument' && <Document newDocument setActiveModal={setActiveModal} />}
123+
</>
124+
</Modal>
125+
)}
126+
</div>
127+
);
128+
};

0 commit comments

Comments
 (0)