4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ReactにFirebaseでGoogleアカウントの情報を反映させる

Posted at

はじめに

Googleが提供しているBaasのサービスであるFirebaseを使えば、バックエンドの知識がなくてもユーザーの管理などができるようになります。
チャットアプリではどのような使い方ができるのかを考えて導入してみました。

Firebaseを導入するアプリ

Firebaseを反映させるのは以下のアプリ。

Firebase編

Firebaseの使い方

今回はFirebaseをユーザー管理に用いました。
具体的には次の操作をできるようにします。

  • Googleアカウントでログイン/ログアウトをする
  • ログインしていればGoogleアカウントの名前でチャットにメッセージを送れる

Firebaseの導入方法

Firebaseの導入方法についてはこちらをご覧ください。
ReactにFirebaseを使ったログイン機能を実装する

実践編

ここからはコードの記入、解説をしていきます。
下の記事で作成したチャットアプリにコードを追加していくため、Reactの前提知識やファイルの構成などが気になった方はご覧ください。
Reactでのチャット作成手順を誰にでもわかるように解説する

Firebaseの設定

自分はsrc/ディレクトリ直下にfirebase/firebase.jsを設定しました。

firebase/firebase.js
import firebase from 'firebase/app'
import 'firebase/auth'

const config = {
  apiKey: "***",
  authDomain: "***",
  databaseURL: "***",
  projectId: "***",
  storageBucket: "***",
  messagingSenderId: "***"
}

firebase.initializeApp(config)

export default firebase

ここでできるコードの解説はほとんどありません。
Firebase consoleからconfigの情報を持ってきて定義し、initializeAppfirebaseの初期設定を行い、exportで他のファイルから読み取れるようにしただけです。
わからないことがあれば、上の自分が作成した記事やFirebaseのドキュメントを確認してみてください。

ログインできるようにする

まずはこのファイルにGoogleアカウントでログインできるようにします。
ユーザーの名前はsrc/components/ChatForm.jsで入力しているため、そこに以下のコードを追加します。

src/components/ChatForm.js
 import firebase from '../firebase/firebase'

 constructor(props){
    super(props)
    this.state = {
      name: '',
      message: '',
      user: null
    }
  }

  componentDidMount(){
    firebase.auth().onAuthStateChanged(user => {
      this.setState({ user })
    })
  }
  //このcomponentがDOMにマウントされた直後、Googleにログインしている状態であればthis.state.userにfirebaseで管理しているuserの値を入れる。

  login() {
    const provider = new firebase.auth.GoogleAuthProvider()
    firebase.auth().signInWithRedirect(provider)
  }
  //ログイン処理をするイベントの設定。今回はGoogleを使用するためGoogleのProviderに接続してGoogleユーザーの情報でログインする。
  logout(){
    firebase.auth().signOut()
  }
  //ログアウト処理をするイベントの設定。

  {this.state.user ?
     <button onClick={this.logout}>Google Logout</button> :
     <button onClick={this.login}>Goggle Login</button> 
  }
  //ログイン、ログアウトするボタンの設定。
  //this.state.userに値が入っていればログアウト処理をするボタンを表示。
  //this.state.userに値が入っていなければログイン処理をするボタンを表示。

ログインしていればGoogleアカウントの名前でチャットにメッセージを送れる

次に、ログインしていればGoogleアカウントの名前でチャットにメッセージを送れるようにします。
自分が採った解決法は、『ログイン時には2つのボタンが表示される。片方はその名前を使用するボタン、もう片方はログアウトするボタン』というものです。
私はstatepropsの遷移や情報の引渡しに関する知識が弱いため、ログインしただけでその名前を使用できるような方法があるかも知れません。
その方法を知っていたり、発見した際には教えていただきたいです。

src/components/ChatForm.js

  nameChanged(e){
    this.setState({name: e.target.value})
  }

  {this.state.user ? (
    //ログインしているかどうかの確認

      <div className='login'>
        <h2>{this.state.user.displayName}</h2>
         //Googleアカウントで使用している名前を表示する
        <button value={this.state.user.displayName} onClick={e => this.nameChanged(e)}>この名前を使用する</button>
         //1つ目のボタン
         //このボタンを押すとthis.state.nameにGoogleアカウントで使用している名前が渡される
        <button onClick={this.logout}>違う名前を使用する</button>
         //2つ目のボタン
         //このボタンを押すとログアウトできる。
      </div>
      //ログインしている時の処理
      ) :(
      <input value={this.state.name} onChange={e => this.nameChanged(e)}/>
     //ログアウトしている時の処理
  )}
       

完成版ChatForm.js

最後にChatForm.jsのコードを一から載せます。

src/components/ChatForm.js
import React,{Component} from 'react'
import socketio from 'socket.io-client'
import firebase from '../firebase/firebase'

const portNumber = process.env.PORT || 3005
const socket = socketio.connect('http://localhost:' + portNumber)

class ChatForm extends Component {
  constructor(props){
    super(props)
    this.state = {
      name: '',
      message: '',
      user: null
    }
  }

  componentDidMount(){
    firebase.auth().onAuthStateChanged(user => {
      this.setState({ user })
    })
  }
  login() {
    const provider = new firebase.auth.GoogleAuthProvider()
    firebase.auth().signInWithRedirect(provider)
  }
  logout(){
    firebase.auth().signOut()
  }
  nameChanged(e){
    this.setState({name: e.target.value})
  }
  messageChanged(e){
    this.setState({message: e.target.value})
  }
  send(){
    socket.emit('chatMessage',{
      name: this.state.name,
      message: this.state.message
    })
    this.setState({message: ''})
  }

  render(){
    return(
      <div id='Form'>
        <div className='Name'>
          名前:
          {this.state.user ? (
            <div className='login'>
              <h2>{this.state.user.displayName}</h2>
              <button value={this.state.user.displayName} onClick={e => this.nameChanged(e)}>この名前を使用する</button>
              <button onClick={this.logout}>違う名前を使用する</button>
            </div>
          ) :(
            <input value={this.state.name} onChange={e => this.nameChanged(e)}/>
          )}
          <br />
          {this.state.user ?
            null : <button onClick={this.login}>Goggle Login</button>
          }
          //ログイン時には2つ目のボタンでログアウトできるため、ここで実装する必要はない。そのためログインのみ実装
        </div>
        <br />
        <div className='Message'>
          メッセージ:
          <br />
          <input value={this.state.message} onChange={e => this.messageChanged(e)} />
        </div>
        <button className='send' onClick={e => this.send()}>送信</button>
      </div>
    )
  }
}

export default ChatForm

実際の動き

今回のコードを追加すると、このように動作します。

最後に

Firebaseを利用して、Reactで作成したチャットに機能を追加することができました。

しかし、利便性には乏しい問題があります。
1つ目のボタンを押してもちゃんと反映されているのかわかりにくかったり、余分がコードが多かったりすることを理解しています。
moduleや他のサービスを調べ、機能の追加だけでなく、利便性の向上も意識して勉強していきたいです。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?