はじめに
Googleが提供しているBaasのサービスであるFirebase
を使えば、バックエンドの知識がなくてもユーザーの管理などができるようになります。
チャットアプリではどのような使い方ができるのかを考えて導入してみました。
Firebaseを導入するアプリ
Firebase
を反映させるのは以下のアプリ。
- URL: Reactチャット
- Github: kaibara/React-chat
Firebase編
Firebaseの使い方
今回はFirebaseをユーザー管理に用いました。
具体的には次の操作をできるようにします。
- Googleアカウントでログイン/ログアウトをする
- ログインしていればGoogleアカウントの名前でチャットにメッセージを送れる
Firebaseの導入方法
Firebase
の導入方法についてはこちらをご覧ください。
ReactにFirebaseを使ったログイン機能を実装する
実践編
ここからはコードの記入、解説をしていきます。
下の記事で作成したチャットアプリにコードを追加していくため、Reactの前提知識やファイルの構成などが気になった方はご覧ください。
Reactでのチャット作成手順を誰にでもわかるように解説する
Firebaseの設定
自分はsrc/
ディレクトリ直下に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の情報を持ってきて定義し、initializeApp
でfirebase
の初期設定を行い、export
で他のファイルから読み取れるようにしただけです。
わからないことがあれば、上の自分が作成した記事やFirebase
のドキュメントを確認してみてください。
ログインできるようにする
まずはこのファイルにGoogleアカウントでログインできるようにします。
ユーザーの名前は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つのボタンが表示される。片方はその名前を使用するボタン、もう片方はログアウトするボタン』というものです。
私はstate
やprops
の遷移や情報の引渡しに関する知識が弱いため、ログインしただけでその名前を使用できるような方法があるかも知れません。
その方法を知っていたり、発見した際には教えていただきたいです。
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
のコードを一から載せます。
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や他のサービスを調べ、機能の追加だけでなく、利便性の向上も意識して勉強していきたいです。