Build A Blog Site With React, Redux Firebase And MaterializeCSS (Part 10)

in #utopian-io5 years ago

react-redux.fw.png

Repository

React

https://github.com/facebook/react

Material-ui

https://github.com/mui-org/material-ui

My Github Address

https://github.com/pckurdu

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.
react1.gif


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.
react2.gif


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.
reac3.gif


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)



react4.gif

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='/' />
…



react5.gif


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)



react6.gif

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

Sort:  

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!

Coin Marketplace

STEEM 0.27
TRX 0.13
JST 0.031
BTC 61374.19
ETH 2885.69
USDT 1.00
SBD 3.55