Build A Blog Site With React, Redux Firebase And MaterializeCSS (Part 10)
Repository
React
https://github.com/facebook/react
Material-ui
https://github.com/mui-org/material-ui
My Github Address
This Project Github Address
https://github.com/pckurdu/Build-A-Blog-Site-With-React-Redux-Firebase-And-MaterializeCSS-Part-10
What Will I Learn?
- You will learn how to restrict access to unauthorized pages via the url.
- You will learn the operating logic of the Redirect module in react-router-dom.
- You will learn to access to the reducer created from the component.
- You will learn the properties of the auth object in firebaseReducer.
- You will learn how to access the user's uid information in firebase with firebaseReducer
Requirements
- text editor (I used visual studio code editor)
- Basic javascript information
- Basic react information
Difficulty
- Basic
Tutorial Contents
In this tutorial we will set the pages that the user will see according to the user login or logout.
If the user has logged in to the page by opening a firebase session, there is no it need to see the signin and signup pages. Likewise, the user should not see the dashboard pages if they are not logged on.
We have provided this control over the links on the previous tutorial navbar. We'll provide control for url in this tutorial. If the user has not logged , they can access the page by typing the necessary extensions in the url in to this part of the application. This also allows the site to be vulnerable and error.
In this tutorial we will solve this problem. In order to understand better, I explained the events that will occur when the user is logged in and not logged in in different sections.
1-Prevent Access to Dashboard Pages From Url
In this section, we will make the necessary settings so that the user does not access the dashboard pages without logging in. Below we can see how the user accesses without login.
We will check the auth object in the firebase reducer to perform this operation. If the auth object is empty, the user is not logged in and the dashboard pages should not be accessed and If the auth object is full, the user can access these pages.
We will use the redirect
module in the react-router-dom packages. Thus you will learn a different aspect of orientation to the desired url address.
We will also learn how to access the reducer from components. To access the auth object, we need to access the reducer from the component, so that we can use this auth object as a props in component.
We can begin performing operations with the dashboard
component.
We have already accessed firestoreReducer
for showing the project list on the dashboard page. Since we need to send all the reducers to the store, we will be able to access all the reducers because we combine them into a file called rootReducer
.In the mapStateToProps
function we can also access firebaseReducer
.
In Dashboard.js
//function that gets data from store
const mapStateToProps=(state)=>{
//console.log(state);
return {
//Let's get the data from the firestore.
projects:state.firestore.ordered.projects,
//We are accessing the auth object in firebaseReducer.
auth:state.firebase.auth
}
}
With this function we can access the auth object in component props
.
If the auth object is empty, let's import the Redirect
object because we'll be redirected.
//import Redirect module
import {Redirect} from 'react-router-dom';
…
//let's use projects and auth object
const {projects,auth}=this.props;
Since we access the auth object, we must control the routing without loading the elements of the dashboard page.
//If uid is empty, user is not logged in.
if(!auth.uid) return <Redirect to='/signin' />
return (
<div className="dashboard container">
<div className="row">
…
So it will go to the signIn page if you try to reach the page by typing in the url field.
As we write security codes for the dashboard page, we can switch to providing security on other dashboard pages. Let's start with the CreateProject
page first.
On this page we were adding data in firestore to the base so we did not reach the reducer. Because we were doing data insertion in action and it was enough for us to access action.
Let's create a function to access the reducer.
In CreateProject.js
//function that gets data from store
const mapStateToProps=(state)=>{
//console.log(state);
return {
//We are accessing the auth object in firebaseReducer.
auth:state.firebase.auth
}
}
export default connect(mapStateToProps, mapDispatchToProps)(CreateProject)
With this function we access the firebaseReducer
and transfer the auth object into props. If we use this function as the first parameter of the connect ()
module, we reach the reducer.
//import Redirect module
import {Redirect} from 'react-router-dom';
…
//let's use auth object
const {auth}=this.props;
//If uid is empty, user is not logged in.
if(!auth.uid) return <Redirect to='/signin' />
We use redirect module as in the same dashboard. If auth.uid is empty, it is redirected to signIn.
ProjectDetails
page is one of the dashboard pages and we need to check this page. We can repeat the operations we have done in the ProjectDetails page.
After performing the operations, the final version of the ProjectDetail component is as follows.
In ProjectDetails.js
import React from 'react'
//import connect module
import {connect} from 'react-redux';
//connect firestore
import { firestoreConnect } from 'react-redux-firebase';
//to merge
import { compose } from 'redux';
//import Redirect module
import {Redirect} from 'react-router-dom';
const ProjectDetails = (props) => {
const {project,auth}=props;
//If uid is empty, user is not logged in.
if(!auth.uid) return <Redirect to='/signin' />
if(project){
return (
// details of a project into the card structure.
<div className="container section project-details">
<div className="card z-depth-0">
<div className="card-content">
<span className="card-title">{project.title}</span>
<p>{project.content}</p>
</div>
<div className="card-action grey lighten-4 grey-text">
<div>Posted by {project.authorName}</div>
<div>2nd September, 2am</div>
</div>
</div>
</div>
)
}else{
return(
<p>Loading project</p>
)
}
}
//function that gets data from store
const mapStateToProps=(state,ownProps)=>{
//the first value written to the console comes from the store.
//console.log(state);
//the second value written to the console comes from this component's props.
//console.log(ownProps);
const id=ownProps.match.params.id;
const projects=state.firestore.data.projects;
const project=projects?projects[id]:null;
return {
project:project,
auth:state.firebase.auth
}
}
export default compose(
connect(mapStateToProps),
firestoreConnect([
{collection:'projects'}
])
)(ProjectDetails)
2-Prevent Access to SignIn And SignUp Pages From Url
If the user is logged in, he no longer needs signUp and signIn. In this section, we will perform url security settings so that the user does not access the signUp and SignIn pages if they are logged on.
We make the necessary settings for the signIn page.
As this page has previously been accessed by the reducer, we can access firabeReducer from that function.
In SignIn.js
//Function to access store
const mapStateToProps=(state)=>{
return {
authError:state.auth.authError,
//We are accessing the auth object in firebaseReducer.
auth:state.firebase.auth
}
}
We need to check the uid property in the auth object. The uid
value is not null
because we expect the user to log in.
//import Redirect module
import {Redirect} from 'react-router-dom';
…
render() {
const {authError,auth}=this.props;
//If uid is not empty, user is logged in.
if(auth.uid) return <Redirect to='/' />
…
Let's repeat these operations in the singUp
page.
Since we did not access the aciton or reducer on this page in previously, let's import the connect module.
In signUp.js
//To access store and reducer
import {connect} from 'react-redux';
//import Redirect module
import {Redirect} from 'react-router-dom';
Then we must define the function that will access the reducers and use it in connect.
//Function to access store
const mapStateToProps=(state)=>{
return {
//We are accessing the auth object in firebaseReducer.
auth:state.firebase.auth
}
}
export default connect(mapStateToProps)(SignUp)
Now we will do necessary process for routing.
ender() {
const {auth}=this.props;
//If uid is not empty, user is logged in.
if(auth.uid) return <Redirect to='/' />
…
We have previously defined signUp as a function. We've translated, necessary to make the necessary changes. To avoid confusion of your head, the following state is available.
In SignUp.js
import React,{Component} from 'react';
//To access store and reducer
import {connect} from 'react-redux';
//import Redirect module
import {Redirect} from 'react-router-dom';
class SignUp extends Component {
render() {
const {auth}=this.props;
//If uid is not empty, user is logged in.
if(auth.uid) return <Redirect to='/' />
return (
<div className="container">
<form className="white">
<h5 className="grey-text text-darken-3">Sign Up</h5>
{/* for email in auth */}
<div className="input-field">
<label htmlFor="email">Email</label>
<input type="email" id='email' />
</div>
{/* for password in auth */}
<div className="input-field">
<label htmlFor="password">Password</label>
<input type="password" id='password'/>
</div>
{/* for first name in firestore */}
<div className="input-field">
<label htmlFor="firstName">First Name</label>
<input type="text" id='firstName' />
</div>
{/* for last name in firestore */}
<div className="input-field">
<label htmlFor="lastName">Last Name</label>
<input type="text" id='lastName' />
</div>
<div className="input-field">
<button className="btn blue lighten-1 z-depth-0">Sign Up</button>
</div>
</form>
</div>
)
}
}
//Function to access store
const mapStateToProps=(state)=>{
return {
//We are accessing the auth object in firebaseReducer.
auth:state.firebase.auth
}
}
export default connect(mapStateToProps)(SignUp)
Curriculum
Part 1 - Part 2 - Part 3 - Part 4 - Part 5 - Part 6 - Part 7 - Part 8 - Part 9
Proof of Work Done
https://github.com/pckurdu/Build-A-Blog-Site-With-React-Redux-Firebase-And-MaterializeCSS-Part-10
Thank you for your contribution @pckurdu.
After reviewing your tutorial we suggest the following points listed below:
Excellent tutorial again. Thanks for following our suggestions in your previous tutorial.
We suggest you try not to repeat the login step.
Thank you for your work in developing this tutorial.
Looking forward to your upcoming tutorials.
Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.
To view those questions and the relevant answers related to your post, click here.
Need help? Chat with us on Discord.
[utopian-moderator]
Thank you for your review, @portugalcoin! Keep up the good work!