【Firebase】FIrestore Databaseから取得したデータを、ブラウザに表示させる
Firebase

【Firebase】FIrestore Databaseから取得したデータを、ブラウザに表示させる

作成日:2022年03月02日
更新日:2022年03月03日

前回は、Firebase Authentication の機能を使って、パスワード再設定機能を実装しました。

firebase-react-password-reset

【Firebase】Reactでパスワード再設定機能を実装する

今回は、Firestore Database からデータを取得し、ブラウザに表示させます。

まずは、Firebase の Firestore Database にアクセスし、データを作成します。

今回は、チャットを作る予定です。

コレクション名を『messages』とします。

フィールドは、text、createdAt、user の name、uid を設定しました。

image2

画面上部の『ルール』をクリックします。

image3

認証されている場合のみデータを取得したいので、if request.auth != null を設定します。

image4

『公開』をクリックしましょう。

次は、作成している React プロジェクトの Home.tsx へ移動します。

AppBarをコンポーネント化しましょう。

src フォルダに components フォルダを作成します。

components フォルダの中に Header.tsx を作成しましょう。

Home.tsx の中身をコピーし、Header.tsx 用に修正します。

tsx
import React, { useState } from "react";
import { useNavigate } from "react-router-dom";
import {
AppBar,
Box,
Toolbar,
IconButton,
Menu,
MenuItem,
Snackbar,
Alert,
} from "@mui/material";
import AccountCircle from "@mui/icons-material/AccountCircle";
import { useLogout } from "../hooks/useAuth";
import { firebaseApp } from "../firebase/firebaseConfig";
export default function Header() {
const { logout } = useLogout();
const navigate = useNavigate();
const [auth, setAuth] = useState(false);
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
const [open, setOpen] = useState(false);
firebaseApp.fireauth.onAuthStateChanged((user) => {
if (!user) {
navigate("/login");
} else {
setAuth(true);
}
});
const handleMenu = (event: React.MouseEvent<HTMLElement>) => {
setAnchorEl(event.currentTarget);
};
const handleLogout = () => {
logout();
setOpen(true);
setAnchorEl(null);
setTimeout(() => {
navigate("/login");
}, 2000);
};
const handleClose = () => {
setAnchorEl(null);
setOpen(false);
};
return (
<Box sx={{ flexGrow: 1 }}>
<AppBar position="static">
<Toolbar sx={{ justifyContent: "right" }}>
{auth && (
<div>
<IconButton
size="large"
aria-label="account of current user"
aria-controls="menu-appbar"
aria-haspopup="true"
onClick={handleMenu}
color="inherit"
>
<AccountCircle />
</IconButton>
<Menu
id="menu-appbar"
anchorEl={anchorEl}
anchorOrigin={{
vertical: "top",
horizontal: "right",
}}
keepMounted
transformOrigin={{
vertical: "top",
horizontal: "right",
}}
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>プロフィール</MenuItem>
<MenuItem onClick={handleLogout}>ログアウト</MenuItem>
</Menu>
</div>
)}
</Toolbar>
</AppBar>
<Snackbar open={open} autoHideDuration={3000} onClose={handleClose}>
<Alert onClose={handleClose} severity="success" sx={{ width: "100%" }}>
ログアウトしました
</Alert>
</Snackbar>
</Box>
);
}

作成した Header.tsx を Home.tsx にインポートします。

tsx
<Box sx={{ flexGrow: 1 }}>
<Header />
</Box>

データを取得するフックを作成するため、hooks フォルダに useFirebase.ts を作成します。

内容な、こちらをご覧ください。

firebase-firestore-database-onsnapshot

【Firebase】Firestore Databeseのデータを、リアルタイムで取得する

ts
import { useState, useEffect } from "react";
import { collection, onSnapshot } from "firebase/firestore";
import { firebaseApp } from "../firebase/firebaseConfig";
const useFirebase = (data: string) => {
const [documents, setDocuments] = useState([]);
useEffect(() => {
const firestore = firebaseApp.firestore;
const docRef = collection(firestore, data);
const unsub = onSnapshot(docRef, (snapshot) => {
let results: any = [];
snapshot.docs.forEach((doc) => {
results.push({ ...doc.data(), id: doc.id });
});
setDocuments(results);
});
return () => unsub();
}, [data]);
return { documents };
};
export default useFirebase;

Home.tsx にuseFirebaseをインポートします。

useFirebase には、先程 FIrestore Database で作成した『messages』コレクションを指定します。

tsx
const { documents: messages } = useFirebase("messages");

Message の型を作成しておきましょう。

createdAtは、firebase/firestoreからTimestampをインポートしておきます。

tsx
interface Message {
id: string;
text: string;
createdAt: Timestamp;
user: {
name: string;
uid: string;
};
}

messagesmapを使って一覧をブラウザに表示させます。

また、データがない場合には、『メッセージが存在しません』と表示させます。

tsx
<Box sx={{ flexGrow: 1 }}>
<Header />
{messages ? (
messages.map((message: Message) => (
<div key={message.id}>
<p>{message.text}</p>
<p>{message.createdAt}</p>
</div>
))
) : (
<p>メッセージが存在しません</p>
)}
</Box>

createdAtが Firebase の timestamp なので、このままではエラーが発生します。

こちらを表示させるために、date-fns をインストールします。

ターミナルで、npm install --save date-fnsを実行します。

date-fnsからformatをインポートします。

tsx
import { format } from "date-fns";

message.createdAtを TypeScript でも読み取れるよう、message.createdAt.toDate()を追加します。

まずは、format の第一引数に、message.createdAt.toDate()、第二引数にどのように表示したいかを指定します。

今回は、2022 年 03 月 02 日と表示するようにします。

tsx
{
format(message.createdAt.toDate(), "yyyy年MM月dd日");
}

一通り完成したので、ブラウザで確認すると、

image5

text で指定した内容と、createdAt の内容が表示されました。

次回は、Firestore Database を使い、React でメッセージ送信機能を実装します。

firebase-react-firestore-create

【Firebase】Firestore Databaseを使い、Reactでメッセージ送信機能を実装する

© 2024あずきぱんウェブスタジオ