Skip to main content

การใช้งาน Firebase Authentication ด้วย React JS

สวัสดีครับ สำหรับในบทความนี้จะเกียวกับ การใช้งาน Firebase Authentication กันครับ โดยในตัวอย่างจะใช้ React Js ซึ่งในบทความนี้จะต่อเนื้องจากบทความที่แล้วครับ

การใช้งาน Firebase Realtime Database ด้วย ReactJs

จาก เนื้อหาในตอนที่แล้ว เราได้ทำการสร้าง App ง่าย ๆ ให้สามารถ บันทึก และ แก้ไข ข้อมูลกันไปแล้ว แต่ในตอนนี้ เราจะมาเพิ่มหน้าจอ ให้สามารถ Login และ Logout ได้ครับ

โดยวิธีการใช้งาน Firebase Authentication โดยละเอียด ดูได้ที่

https://firebase.google.com/docs/auth/web/password-auth?authuser=0

ก่อนอื่นเรามาแก้ไขไฟล์ firebase.js กันก่อนครับ

โดยเราจะเพิ่ม export const auth = firese.auth(); เพื่อใช้งาน ฟังชั่น authentication ครับ

import * as firebase from 'firebase';

//insert config from firebase
const config = {
    apiKey: "AIzaSyBaYasdfmYbormmmRHpff2WasdfMuYVBDas6ev3G9k",
    authDomain: "toasdfdo-7ffasdfb6.firebaseapp.com",
    databaseURL: "https://todo-7asdfffb6.firebaseio.com",
    projectId: "todo-7ffbasdf6",
    storageBucket: "todo-7ffasdfb6.appspot.com",
    messagingSenderId: "2458asdf3sdf9549110"
};
firebase.initializeApp(config);

//add code firebase.auth
export const auth = firebase.auth();

export default firebase;

 

ต่อมาเรามาแก้ไขไฟล์ App.js กันต่อเลยครับ

ในส่วนของ import firebase เพิ่ม การเรียกใช้งาน function auth ของ firebase

import React, { Component } from 'react';

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

class App extends Component {

ในส่วนของ state เราจะทำการเพิ่ม state email,password, และ isLogin ใช้สำหรับตรวจสอบว่าได้มีการ Login แล้ว หรือยังโดยค่าเร่ิมต้นคือ false หมายถึงยังไม่ได้ Login

     this.state = {
        items:[],
        item_id:'',
        title:'',
        description:'',
        email:'',//add email state
        password:'',//add password state
        isLogin:false //add isLogin state
     }

ใน constructor เพิ่มการ bind ใน function login และ logout เพื่อให้สามารถ จัดการ กับ ค่าที่อยู่ภายใน state ได้

     this.login = this.login.bind(this)
     this.logout = this.logout.bind(this)

เพิ่ม function login และ logout

ใน function login จะมีการเรียกใช้งาน  signInWithEmailAndPassword โดยมีการส่ง email ,password เพื่อไปตรวจสอบว่า เป็นผู้ใช้จริงหรือไม่ หาก จริง จะมีการ setState ให้ isLogin เป็น true

ในส่วนของ function logout เรียกใช้งาน auth.signOut หากสำเร็จ  จะมีการ setState ให้ isLogin เป็น false

 login = () =>{
   
  firebase.auth().signInWithEmailAndPassword(this.state.email, this.state.password).then(() => {
   
   this.setState({ isLogin : true });

  }).catch(function(error) {
     var errorCode = error.code;
     var errorMessage = error.message;
     if (errorCode === 'auth/wrong-password') {
       alert('Wrong password.');
     } else {
       alert(errorMessage);
     }
     console.log(error);
   });
}

logout(){
  auth.signOut().then(() => {
     this.setState({isLogin:false})
  }) 
}

เพิ่ม function loginForm เพื่อแสดงหน้า สำหรับ กรอก Username , Password

loginForm(){
  return(
    <div>
         <main role="main" className="container" style={{marginTop:80}}>
         <div className="row">
           <div className="col-4"></div>
             <div className="col-4">
                 <form>
                   <div class="form-group">
                     <label for="exampleInputEmail1">Email address</label>
                     <input type="email" class="form-control" name="email"  onChange={this.handleChange} value={this.state.email} placeholder="Enter email"/>
                     <small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
                   </div>
                   <div class="form-group">
                     <label for="exampleInputPassword1">Password</label>
                     <input type="password" class="form-control" name="password" onChange={this.handleChange} value={this.state.password} placeholder="Password"/>
                   </div>
                   <a class="btn btn-primary" onClick={() => this.login()}>Log In</a>
                 </form>
             </div>
           </div>
         </main>
     </div>
  )
}

เพิ่มการตรวจสอบว่า ได้มีการ Login แล้วหรือยัง โดยหาก isLogin เป็น false ให้เรียกใช้งาน loginForm

  render() {

  if(!this.state.isLogin){
      return this.loginForm()
   }
 //....

เพิ่มการแสดงปุ่ม Logout เมื่อ isLogin มีค่าเป็น true

    return (
      <div className="app">
          <nav class="navbar navbar-light bg-primary">
            <span class="navbar-brand mb-0 h1">Todo List</span>
            {
                this.state.isLogin ? <a className="btn btn-danger"  onClick={() => this.logout()} >Logout</a> : null 
            }
          </nav>
//..

จากนั้นทดลอง run คำสั่ง npm start  จะพบกับหน้าจอ Login

มาถึงตอนนี้เราก็ได้เพิ่ม Code ในส่วนของการ Authentication ด้วย Firebase เรียบร้อยแล้ว แต่ยังไม่สามารถใช้งานได้ เนื่องจากเราต้องไปทำการเปิดใช้งาน Authentication ใน Firebase Control กันก่อนครับ

การเปิดใช้งาน Firebase Authentication

1.ไปที่ https://console.firebase.google.com/u/0/

2.ในตัวอย่างจะเลือก Project todo ซึ่งเป็น Project เดิมจากตอนที่แล้วครับ
จากนั้นเลือกที่ เมนู Authentication จากนั้นเลือก เมนู วิธีการลงชื่อเข้าใช้ ใน Tab ด้านบน ครับ

3.เลือกที่ หัวข้อ อีเมล/รหัสผ่าน จากนั้นให้คลิก เปิดใช้งาน และ บันทึกครับ

4. ไปที่ Tab ผู้ใช้ ด้านบน ทำการเพิ่ม User ที่เราต้องการ โดยการคลิกที่ปุ่ม เพิ่มผู้ใช้ครับ

5.เสร็จสิ้นข้อตอนการตั้งค่าที่ Firebase ครับ

ทำการทดสอบที่หน้าเว็บ React Js ที่เราสร้างขึ้น หาก Login สำเร็จจะแสดงหน้า ของ todo List
เมื่อกด Logout ก็จะเปลี่ยนหน้า Login ขึ้นมาครับ

ตัวอย่างไฟล์ App.js แบบเต็ม ๆ

import React, { Component } from 'react';

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

class App extends Component {

  constructor(){
     super();
     this.state = {
        items:[],
        item_id:'',
        title:'',
        description:'',
        email:'',//add email state
        password:'',//add password state
        isLogin:false //add isLogin state
     }

     this.handleChange = this.handleChange.bind(this)
     this.handleUpdate = this.handleUpdate.bind(this)
     this.handleSubmit = this.handleSubmit.bind(this)

     this.login = this.login.bind(this)
     this.logout = this.logout.bind(this)

  }

  componentDidMount(){

      auth.onAuthStateChanged((user) => {
          if(user){
            this.setState({user})
          }
      })

      const itemsRef = firebase.database().ref('items');
      itemsRef.on('value',(snapshot) => {
          let items = snapshot.val();
          let newState = [];
          for(let item in items){
            newState.push({
                item_id:item,
                title:items[item].title,
                description:items[item].description
            })
          }
          this.setState({
            items:newState
          })
      })
  }

  handleChange(e){
    this.setState({
      [e.target.name]: e.target.value
    })
  }


  handleSubmit(e){
    e.preventDefault();

    if(this.state.item_id !== ''){
      return this.updateItem();
    }

    const itemsRef = firebase.database().ref('items')
    const item = {
       title : this.state.title,
       description : this.state.description
    }
    itemsRef.push(item)
    this.setState({
       item_id:'',
       title:'',
       description:''
    })
 }


  handleUpdate = (item_id = null , title = null , description = null) => {
    this.setState({item_id,title,description})
  }

  updateItem(){

      var obj = { title:this.state.title,description:this.state.description }

      const itemsRef = firebase.database().ref('/items')

      itemsRef.child(this.state.item_id).update(obj);

      this.setState({
        item_id:'',
        title:'',
        description:''
      })

  }

  removeItem(itemId){
    const itemsRef = firebase.database().ref('/items');
    itemsRef.child(itemId).remove();
 }


 login = () =>{

  firebase.auth().signInWithEmailAndPassword(this.state.email, this.state.password).then(() => {
   
   this.setState({ isLogin : true });

  }).catch(function(error) {
     var errorCode = error.code;
     var errorMessage = error.message;
     if (errorCode === 'auth/wrong-password') {
       alert('Wrong password.');
     } else {
       alert(errorMessage);
     }
     console.log(error);
   });
}

logout(){
  auth.signOut().then(() => {
     this.setState({isLogin:false})
  }) 
}


loginForm(){
  return(
    <div>
         <main role="main" className="container" style={{marginTop:80}}>
         <div className="row">
           <div className="col-4"></div>
             <div className="col-4">
                 <form>
                   <div class="form-group">
                     <label for="exampleInputEmail1">Email address</label>
                     <input type="email" class="form-control" name="email"  onChange={this.handleChange} value={this.state.email} placeholder="Enter email"/>
                     <small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
                   </div>
                   <div class="form-group">
                     <label for="exampleInputPassword1">Password</label>
                     <input type="password" class="form-control" name="password" onChange={this.handleChange} value={this.state.password} placeholder="Password"/>
                   </div>
                   <button class="btn btn-primary" onClick={() => this.login()}>Log In</button>
                 </form>
             </div>
           </div>
         </main>
     </div>
  )
}


  render() {


  if(!this.state.isLogin){
      return this.loginForm()
   }


    return (
      <div className="app">
          <nav class="navbar navbar-light bg-primary">
            <span class="navbar-brand mb-0 h1">Todo List</span>
            {
                this.state.isLogin ? <button className="btn btn-danger"  onClick={() => this.logout()} >Logout</button> : null 
            }
          </nav>
          <div className="container" style={{marginTop:70}}>
          <form  onSubmit={this.handleSubmit}>
            <div className="row">
                <div className="col-8">
                  <div className="form-row">
                    <div className="col-4">
                      <input type="text" name="title" className="form-control" placeholder="Title" onChange={this.handleChange} value={this.state.title}/>
                    </div>
                    <div className="col-6">
                      <input type="text" name="description" className="form-control" placeholder="Description" onChange={this.handleChange} value={this.state.description}/>
                    </div>
                    <div className="col">
                          <button class="btn btn-primary" > Save</button>      
                    </div>
                  </div>
                </div>
            </div>
          </form>
        <hr/>
              <table className="table table-sm table-bordered">
                    <tr className="thead-dark">
                      <th width="20%">Title</th>
                      <th width="70%">Description</th>
                      <th width="5%">Edit</th>
                      <th width="5%">Delete</th>
                    </tr>
                    {
                        this.state.items.map((item) => {
                          return (
                              <tr>
                                <td>{item.title}</td>
                                <td>{item.description}</td>
                                <td><button className="btn btn-warning btn-sm" onClick={() => this.handleUpdate(item.item_id,item.title,item.description)}>Edit</button></td>
                                <td><button className="btn btn-danger btn-sm" onClick={() => this.removeItem(item.item_id)}>Delete</button></td>
                              </tr>
                          )
                        })
                    }
                </table>
          </div>
      </div>
    );
  }
}

export default App;

 


Deprecated: Function create_function() is deprecated in /home/service1/domains/monkeywebstudio.com/public_html/wp-content/plugins/simple-lightbox/controller.php on line 1642