初めに
業務システムの開発で firebase
を使おうとなった時にfirebase SDK
をそのまま使用したくないと思ったので (SDKにあまり依存させたくないという思い) 何かライブラリなどないかと調べたところ本記事タイトルのReact-Firebase-Hooks とReact-Query-Firebase を見つけたので両者の検証, 比較をしようと思います。
Firestoreからのデータ取得
Firestore Database
からのデータ取得の実装コードです。
React-Firebase-Hooks
import { collection } from 'firebase/firestore';
import React from 'react';
import { useCollection } from 'react-firebase-hooks/firestore';
import { db } from '@/lib/firebase';
const ReactFirebaseHooksSample = () => {
const [snapshot, isLoading, error] = useCollection(collection(db, 'users'), {
snapshotListenOptions: { includeMetadataChanges: true },
});
return (
<div>
<p>
{error && <strong>Error: {JSON.stringify(error)}</strong>}
{isLoading && <span>Collection: Loading...</span>}
{snapshot && (
<span>
Collection:{' '}
{snapshot.docs.map((doc) => (
<React.Fragment key={doc.id}>{JSON.stringify(doc.data())}, </React.Fragment>
))}
</span>
)}
</p>
</div>
);
};
React-Query-Firebase
import { useFirestoreQuery } from '@react-query-firebase/firestore';
import { collection, query } from 'firebase/firestore';
import React from 'react';
import { db } from '@/lib/firebase';
const ReactFirebaseHooksSample = () => {
const ref = query(collection(db, 'users'));
const usersQuery = useFirestoreQuery(['users'], ref);
const { data: snapshot, isLoading, error } = usersQuery;
return (
<div>
<p>
{error && <strong>Error: {JSON.stringify(error)}</strong>}
{isLoading && <span>Collection: Loading...</span>}
{snapshot && (
<span>
Collection:{' '}
{snapshot.docs.map((doc) => (
<React.Fragment key={doc.id}>{JSON.stringify(doc.data())}, </React.Fragment>
))}
</span>
)}
</p>
</div>
);
};
Firebase Authを利用したログイン・ログアウト
Firestore Authentication
を利用した認証周りの実装コードです。
React-Firebase-Hooks
import { signInWithEmailAndPassword, signOut } from 'firebase/auth';
import React from 'react';
import { useAuthState } from 'react-firebase-hooks/auth';
import { auth } from '@/lib/firebase';
const login = async () => {
await signInWithEmailAndPassword(auth, 'test@gmail.com', 'password');
};
const logout = async () => {
await signOut(auth);
};
const ReactFirebaseHooksSample = () => {
const [user, isLoading, error] = useAuthState(auth);
return (
<div>
<p>
{error && <strong>Error: {error}</strong>}
{isLoading && <span>Collection: Loading...</span>}
</p>
{user && (
<div>
<p>Current User: {user.email}</p>
<button onClick={logout}>Logout</button>
</div>
)}
<button onClick={login}>Login</button>
</div>
);
};
React-Query-Firebase
import { useAuthUser } from '@react-query-firebase/auth';
import { signInWithEmailAndPassword, signOut } from 'firebase/auth';
import React from 'react';
import { auth } from '@/lib/firebase';
const login = async () => {
await signInWithEmailAndPassword(auth, 'test@gmail.com', 'password');
};
const logout = async () => {
await signOut(auth);
};
const ReactQueryFirebaseSample = () => {
const { data: user, isLoading, error } = useAuthUser(['user'], auth);
return (
<div>
<p>
{error && <strong>Error: {error}</strong>}
{isLoading && <span>Collection: Loading...</span>}
</p>
{user && (
<div>
<p>Current User: {user.email}</p>
<button onClick={logout}>Logout</button>
</div>
)}
<button onClick={login}>Login</button>
</div>
);
};
比較・考察
コード量, SDKへの依存度ともにほぼ等しいと言える結果になりました。
これらの結果からでは, 両者に大きな差はないためどちらを使っても変わらないと思われます。
しかし, React-Query-Firebaseについてみると, クエリを投げる関数の引数にクエリキーをしていることがわかります。ここで, 公式のREADMEから抜粋した一文について見てみます。
Data fetching is handled via Queries and Query Keys, meaning components can share > data throughout your application without needless database reads. (データの取得は、クエリとクエリキーで処理されます。つまり、コンポーネントは、不必要なデータベース読み取りをすることなく、アプリケーション全体でデータを共有することができます。)
このようにReact-Query-Firebaseでは必要なデータのみに焦点を絞ってデータを取得するので, パフォーマンス向上を狙えるのではないかなと思います。
感想
ここまで読んでくださった方は結局どっちが良いのかと思われるかもしれませんが, 個人的にはReact-Query-Firebaseに軍配が上がるのではないかと思います。
理由としては, 上記で挙げたパフォーマンスの観点以外にも, 以下のような強みがあります。
- React-Query-Firebaseは
React Query
上に構築されているため, React Queryの旨味も持っている - ユーザーのサインイン、ドキュメントの削除、トランザクションの実行、イベントの記録などの処理を
Mutation
を介して行うことで複雑なローカルローディングやエラーステートの管理などに手間をとられずにアプリケーションに集中することができる。
もう一方のReact-Firebase-Hooksについては, 記述量が少なくなる
という点以外に強みが見当たリませんでした。(気付いてないだけかもしれませんが)
参考
https://github.com/CSFrequency/react-firebase-hooks/tree/v4.0.2
https://github.com/invertase/react-query-firebase
https://react-query-firebase.invertase.dev/