開発環境:React/Next.js + Firebase
対象読者:FirebaseのAuthenticationに登録されているユーザ一覧を表示したい。Firebase admin SDKでうまくできない。
読んだ後:コレクションを追加してユーザ一覧の表示ができる。
方法
Firebase admin SDKを使って実装していましたがエラー解決ができず。。
少々冗長かもしれませんが以下の方法で実装しました。
- 新規登録時に「customerIndex」コレクションを作成し、名前、email、登録日を登録する
- customerIndexコレクションの全データをforEachで回して表示させる
試行錯誤して辿り着いたのでもっといい方法あれば教えてください。
データ構成
こちらを使って登録者の一覧を表示していきます。
ドキュメントにはAuthenticationのuidを持たせています。
customerIndexコレクションにユーザを登録
//登録者一覧データへの登録
function addCustomersIndex(props){
let registerDate = new Date(props.currentUser.metadata.creationTime)
let month = registerDate.getMonth() + 1;
db.collection('customersIndex').doc(props.currentUser.uid).set({
name: props.currentUser.displayName,
email:props.currentUser.email,
//登録日をyyyy/mm/ddのフォーマットに変更して登録
creationDate: registerDate.getFullYear()+'/'+month+'/'+registerDate.getDate()
}, { merge: true });
}
登録日は任意のフォーマットに変更して登録します。
登録者一覧を表示する
useReducerを使います。
useReducer:state管理ができる。複雑なロジックがある場合に使用。
今回は配列の中にオブジェクトでデータを持たせるという少し複雑な構成なので、useStateでは配列にデータを入れようとしても上書きされてしまいうまくいきませんでした。(これに気がつかなくて時間がかかりました)
先にuseReducerの説明を少し。
reducer:stateを更新するための関数。stateとactionを受け取って新しいstateを返す。
initialState:stateの初期値。
state:コンポーネントの状態。
dispatch:reducerを実行するための呼び出し関数。
import Header from '../components/Head'
import Router from 'next/router';
import Link from 'next/link'
import 'bootstrap/dist/css/bootstrap.css'
import { useEffect,useReducer } from 'react';
import { db,auth } from '../lib/db'
export default function admin() {
return (
<div>
<Header title='管理者ページ'></Header>
<div className="container">
<div className="text-center">
<h1 className="pt-4 pb-4">登録者一覧</h1>
</div>
<AdminIndex />
</div>
</div>
)
}
function AdminIndex() {
const initialState = [];//stateの初期値
//stateを更新するための関数。stateとactionを受け取る。actionのtypeによってstateの更新方法を変える。今回はADDのみ。
const reducer = (state, action) => {
switch (action.type) {
case "ADD":
return [
...state,
{
id:action.info.id,
name: action.info.name,
email: action.info.email,
creationDate:action.info.creationDate
}
];
}
};
const [customers, dispatch] = useReducer(reducer, initialState);
useEffect(() => {
//customersIndexに入っているデータを取り出してcustomersに入れていく
db.collection("customersIndex").get().then(query => {
query.forEach((doc) => {
let data = doc.data();
//reducerを実行するための呼び出し関数。typeとデータを渡す
dispatch({type: 'ADD', info: {id: doc.id, email:data.email,name: data.name,creationDate:data.creationDate}})
});
})
.catch((error)=>{
console.log(`データの取得に失敗しました (${error})`);
});
}, [])
return (
<div>
<table>
<thead>
<tr>
<th>氏名</th>
<th>emailアドレス</th>
<th>登録日</th>
</tr>
</thead>
<tbody>
{customers.map(function (customer) {
return (
<tr name={customer.email} key={customer.email}>
<td>{customer.name}</td>
<td>{customer.email}</td>
<td>{customer.creationDate}</td>
</tr>
)
})}
</tbody>
</table>
</div>
)
}
これでテーブルに登録ずみのユーザが一覧で表示されます。