Hi all, In previous EPI I have explained you how I created separate modules with routes to deal with different URLs.

Previous EPI

To integrate firebase to application, I have created a user account in Firebase console. Then I have enabled Email/Password provider in SIGN-IN METHOD. There are more sign in method features provided by firebase and if you want to integrate those, such as Facebook, Gmail just click enable button.

choose Email/Password provider

Next, we can find our configuration in the project settings on our dashboard. There have access to all the necessary information: secrets, keys, ids and other properties. It needs to next step in ChainKeeper React application.

Then I have created seperate folder to maintain the firebase codes. in that folder I have created 3 files index.js (simple entry point file to the Firebase module), firebase.js (all the configuration goes there)and auth.js ( Firebase authentication API will be defined to sign up, sign in, sign out etc.) files.

To setup the firebase configurations I have update the firebase.js file as follows,

import * as firebase  from 'firebase';

const config = {
apiKey: YOUR_API_KEY,
authDomain: YOUR_AUTH_DOMAIN,
databaseURL: YOUR_DATABASE_URL,
projectId: YOUR_PROJECT_ID,
storageBucket: '',
messagingSenderId: YOUR_MESSAGING_SENDER_ID,
};

if (!firebase.apps.length) {
firebase.initializeApp(config);
}

const auth = firebase.auth();
const googleProvider = new firebase.auth.GoogleAuthProvider();

export default firebase;
const database = firebase.database();
export {
auth,
googleProvider,
database,
};

Then I have updated the index.js file as follows,

import * as auth from './auth';
import * as firebase from './firebase';
import * as db from './db';

export {
auth,
db,
firebase,
};

Then I have implemented firebase APIs in auth.js file for different services.

import { auth } from './firebase';

// Sign Up
export const doCreateUserWithEmailAndPassword = (email, password) =>
auth.createUserWithEmailAndPassword(email, password);

// Sign In
export const doSignInWithEmailAndPassword = (email, password) =>
auth.signInWithEmailAndPassword(email, password);

// Sign out
export const doSignOut = () =>
auth.signOut();

// Password Reset
export const doPasswordReset = (email) =>
auth.sendPasswordResetEmail(email);

// Password Change
export const doPasswordUpdate = (password) =>
auth.currentUser.updatePassword(password);

So now we have done the hard part in the application. Now we remain thing is the connect out front end with these firebase APIs. Now lets see it.

Sign-Up Component

In signup component, I used for main fields from user when sign up. Username,email, passwordOne, passwordTwo. Here is the updated code of the signup component.

import React, { Component } from 'react';
import { Link,withRouter, } from 'react-router-dom';

import * as routes from '../constants/routes';
import { auth, db } from '../firebase';
import LoginwithGoogle from './LoginwithGoogle';

const INITIAL_STATE = {
username:'',
email: '',
passwordOne: '',
passwordTwo: '',
error: null,
};

const SignUpPage = ({ history }) =>
<div>
<SignUpForm history={history} />
</div>

const byPropKey = (propertyName, value) => () => ({
[propertyName]: value,
});

class SignUpForm extends Component {
constructor(props) {
super(props);

this.state = { ...INITIAL_STATE };
}

onSubmit = (event) => {
const {
username,
email,
passwordOne,
} = this.state;

const {
history,
} = this.props;

auth.doCreateUserWithEmailAndPassword(email, passwordOne)
.then(authUser => {
// Create a user in your own accessible Firebase Database too
db.doCreateUser(authUser.uid, username, email)
.then(() => {
this.setState(() => ({ ...INITIAL_STATE }));
history.push(routes.LANDING);
})
.catch(error => {
this.setState(byPropKey('error', error));
});
})
.catch(error => {
this.setState(byPropKey('error', error));
});

event.preventDefault();
}


render() {
const {
username,
email,
passwordOne,
passwordTwo,
error,
} = this.state;

const isInvalid =
passwordOne !== passwordTwo ||
passwordOne === '' ||
email === '' ||
username === '';

return (
<div className="limiter main-back">
<div className="container-login100 back-login">
<div className="wrap-login100">
<form className="login100-form validate-form" onSubmit={this.onSubmit}>
<span className="login100-form-title p-b-1" style={{marginTop:"-40px",color:'#52595b', fontSize:'16px',fontFamily: 'Poppins-Regular'}}>
Welcome to the
</span>
<span className="login100-form-title p-b-48">
<img src={require('../../public/images/l.jpeg')} style={{width:'240px'}} alt="true" />
</span>

<div className="wrap-input100 validate-input">
<input
value={username}
onChange={event => this.setState(byPropKey('username', event.target.value))}
type="text"
className="input100"
placeholder="Enter Name"
/>
</div>

<div className="wrap-input100 validate-input">
<input
value={email}
onChange={event => this.setState(byPropKey('email', event.target.value))}
type="email"
className="input100"
placeholder="Email Address"
/>
</div>

<div className="wrap-input100 validate-input">
<span className="btn-show-pass">
<i className="zmdi zmdi-eye" />
</span>
<input
value={passwordOne}
onChange={event => this.setState(byPropKey('passwordOne', event.target.value))}
type="password"
className="input100"
placeholder="Password"
/>
</div>

<div className="wrap-input100 validate-input">
<span className="btn-show-pass">
<i className="zmdi zmdi-eye" />
</span>
<input
value={passwordTwo}
onChange={event => this.setState(byPropKey('passwordTwo', event.target.value))}
type="password"
className="input100"
placeholder="Confirm Password"
/>
</div>

<div className="container-login100-form-btn">
<div className="wrap-login100-form-btn">
<div className="login100-form-bgbtn"/>
<button className="login100-form-btn" disabled={isInvalid} type="submit">
Sign Up
</button>
</div>
</div>

<div className="text-center p-t-10">
<span className="txt1">
{ error && <p style={{color:'#aa1d1d'}}>{error.message}</p> }
</span>
</div>

<div className="text-center p-t-15">
<span className="txt1">
<p>
Have an account?
{' '}
<Link to={routes.SIGN_IN}><b>Sign In</b></Link>
</p>
</span>
</div>

<hr />
<div className="text-center p-t-15">
<span className="txt1">
<LoginwithGoogle />
</span>
</div>

</form>
</div>
</div>
</div>
);
}
}

const SignUpLink = () =>
<p>
Don't have an account?
{' '}
<Link to={routes.SIGN_UP}><b>Sign Up</b></Link>
</p>

export default withRouter(SignUpPage);

export {
SignUpForm,
SignUpLink,
};

I will explain this in simple way. In render part I have included my user interface part. When user submit the records with the signup form application automatically trigger the onSubmit function and it gets user entered fields. Then it passes all the records to the firebase API auth.doCreateUserWithEmailAndPassword(email, passwordOne) to create a new user.

Sign-In Component

In signin component, User needs to enter two fields when sign up as normal logins. Email, password. Here is the updated code of the signin component.

import React, { Component } from 'react';
import { withRouter } from 'react-router-dom';

import { SignUpLink } from './SignUp';
import { PasswordForgetLink } from './PasswordForget';
import LoginwithGoogle from './LoginwithGoogle';
import { auth } from '../firebase';
import * as routes from '../constants/routes';

const SignInPage = ({ history }) =>
<div>
<SignInForm history={history} />
</div>

const byPropKey = (propertyName, value) => () => ({
[propertyName]: value,
});

const INITIAL_STATE = {
email: '',
password: '',
error: null,
};

class SignInForm extends Component {
constructor(props) {
super(props);
this.state = { ...INITIAL_STATE };
}

onSubmit = (event) => {
const {
email,
password,
} = this.state;

const {
history,
} = this.props;

auth.doSignInWithEmailAndPassword(email, password)
.then(() => {
this.setState(() => ({ ...INITIAL_STATE }));
history.push(routes.LANDING);
})
.catch(error => {
this.setState(byPropKey('error', error));
});

event.preventDefault();
};

render() {
const {
email,
password,
error,
} = this.state;

const isInvalid =
password === '' ||
email === '';

return (
<div className="limiter main-back">
<div className="container-login100 back-login">
<div className="wrap-login100">
<form className="login100-form validate-form" onSubmit={this.onSubmit}>
<span className="login100-form-title p-b-1" style={{marginTop:"-40px", color:'#52595b', fontSize:'16px',fontFamily: 'Poppins-Regular'}}>
Welcome to the
</span>
<span className="login100-form-title p-b-48">
<img src={require('../../public/images/l.jpeg')} style={{width:'240px'}} alt="true" />
</span>

<div className="wrap-input100 validate-input" data-validate="Valid email is: a@b.c">
<input
value={email}
onChange={event => this.setState(byPropKey('email', event.target.value))}
type="text"
className="input100"
placeholder="Email"
/>
</div>

<div className="wrap-input100 validate-input" data-validate="Enter password">
<span className="btn-show-pass">
<i className="zmdi zmdi-eye" />
</span>
<input
value={password}
onChange={event => this.setState(byPropKey('password', event.target.value))}
type="password"
className="input100"
placeholder="Password"
/>
</div>

<div className="container-login100-form-btn">
<div className="wrap-login100-form-btn">
<div className="login100-form-bgbtn"/>
<button className="login100-form-btn" disabled={isInvalid} type="submit">
Sign In
</button>
</div>
</div>


<div className="text-center p-t-10">
<span className="txt1">
{ error && <p style={{color:'#aa1d1d'}}>{error.message}</p> }
</span>
</div>

<div className="text-center p-t-10">
<span className="txt1">
<PasswordForgetLink />
</span>
</div>

<div className="text-center p-t-15">
<span className="txt1">
<SignUpLink />
</span>
</div>

<hr />
<div className="text-center p-t-15">
<span className="txt1">
<LoginwithGoogle />
</span>
</div>

</form>
</div>
</div>
</div>
);
}
}

export default withRouter(SignInPage);

export {
SignInForm,
};

I will explain this in simple way. In render part I have included my user interface part. When user submit the records with the signin form application automatically trigger the onSubmit function and it gets user entered fields. Then it passes all the records to the firebase API auth.doSignInWithEmailAndPassword(email, password) to verify the user.

Sign-Out Component

Here is the sign out component.

import React from 'react';

import { auth } from '../firebase';

const SignOutButton = () =>
<button
type="button"
onClick={auth.doSignOut}
style={{backgroundColor:'transparent'}}
>
Sign Out
</button>

export default SignOutButton;

Here are the simple steps of creating Firebase + React authentication application, In this way I have achieved my authentication process. So that’s it.

So in ChainKeeper now we have strong authentication mechanism with firebase. In next article I will explain you a another feature of ChainKeeper Blockchain_REST_API with BlockSci. How it implemented and how it works.

Stay tuned! :)

--

--

Sajitha Liyanage

Software Engineer @ WSO2 | Open Source Contributor | Computer Science Graduate @ UCSC