udemyでfirebase8を使用したtodoリストの作成をしたので、リファクタリングの練習として、firebase8→firebase9への書き換えを行う。
最初からfirebase9に書き換えながらudemyの講座を進めて行けば効率が良さそうですが、私は決して優秀ではないので、一つのこと(完成させる)に集中するために、講座とバージョンを合わせて行いました。
それでは、公式ドキュメントを参考に進めていきます。
Upgrade from the namespaced API to the modular API | Firebase
v8とv9を共存させる
npmを使用して、v9ライブラリとcompatライブラリを入手する
npm ifirebase@9.9.3
importを書き換える
import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
↓
import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/firestore';
これで、エラーはなくなるはず。他のファイルでもfirebaseを読み込んでいる場合はそちらも書き換える。
初期化をv8とv9の両方で行う
これにより、v8
とv9
を共存させながら、v9
へ以降できます。
import firebase from 'firebase/compat/app';
import { initializeApp } from "firebase/app" //v9
import 'firebase/compat/auth';
import 'firebase/compat/firestore';
firebase.initializeApp({
apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
databaseURL: process.env.REACT_APP_FIREBASE_DATABASE_URL,
projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.REACT_APP_FIREBASE_SENDER_ID,
appId: process.env.REACT_APP_FIREBASE_APP_ID,
measurementId: process.env.REACT_APP_FIREBASE_MEASUREMENT_ID,
});
const firebaseApp = initializeApp({
apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
databaseURL: process.env.REACT_APP_FIREBASE_DATABASE_URL,
projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.REACT_APP_FIREBASE_SENDER_ID,
appId: process.env.REACT_APP_FIREBASE_APP_ID,
measurementId: process.env.REACT_APP_FIREBASE_MEASUREMENT_ID,
});
モジュラースタイルへリファクタリング
認証関数のリファクタリング
import 'firebase/compat/auth'; //v8
import { getAuth } from "firebase/auth"; //v9
// export const auth = firebase.auth(); //v8
export const auth = getAuth(app); //v9
import { onAuthStateChanged } from "firebase/auth";
useEffect(() => {
// auth.onAuthStateChanged(setCurrentUser); //v8
onAuthStateChanged(auth, setCurrentUser); //v9
}, []);
CloudFirestore関数のリファクタリング
import { getFirestore } from "firebase/firestore"; //9
// export const db = firebase.firestore(); //v8
const db = getFirestore(firebaseApp); //v9
データの追加書き込み
import { collection, addDoc, query, orderBy, serverTimestamp } from "firebase/firestore";
export const addTodo = async (content, uid) => {
// db.collection('todo').add({
// content: content,
// createdAt: firebase.firestore.FieldValue.serverTimestamp(),
// isComplete: false,
// uid: uid
// })
↓
await addDoc(collection(db, 'todo'), {
content: content,
createdAt: serverTimestamp(),
isComplete: false,
uid: uid
})
}
データの取得
import { collection, addDoc, query, orderBy, doc, where, getDocs } from "firebase/firestore";
export const initGet = async (uid) => {
// const todo = await db
// .collection('todo')
// .orderBy('createdAt', 'desc')
// .where('uid', '==', uid);
const todo = await query(collection(db, 'todo'), where('uid', '==', uid));
const querySnapshot = await getDocs(todo);
// return todo.get().then((snapShot) => {
return (() => {
console.log(`snapshot get`)
let todos = [];
querySnapshot.forEach((doc) => {
todos.push({
id: doc.id,
content: doc.data().content,
isComplete: doc.data().isComplete
});
});
return todos;
});
}
データの削除
import { collection, addDoc, query, orderBy, doc, where, getDocs, deleteDoc } from "firebase/firestore";
export const todoDelete = async (id) => {
// db.collection('todo').doc(id).delete(); //8
await deleteDoc(doc(db, 'todo', id))
}
ドキュメントの更新
import { updateDoc, serverTimestamp, doc } from "firebase/firestore";
export const toggleComplete = async (id) => {
// const todo = await db.collection('todo').doc(id).get();
const todo = await doc(db, 'todo', id)
// return db.collection('todo').doc(id).update({
return updateDoc(todo, {
// isComplete: todo.data().isComplete ? false : true, //v8
isComplete: todo.isComplete ? false : true,
// updateAt: firebase.firestore.FieldValue.serverTimestamp(), //v8
updateAt: serverTimestamp(), //v9
})
}
データの編集
const updateContent = async (postId: string, inputValue: string) => {
const todo = doc(db, 'todos', postId)
await updateDoc(todo, {
content: inputValue,
updateAt: serverTimestamp(),
})
}
サインイン
import { getAuth, GoogleAuthProvider, signInWithPopup, signOut } from "firebase/auth"; //v9
export const singInWithGoogle = () => {
// firebase.auth().signInWithPopup(provider).then((res) => {
// console.log(res.user);
// }).catch((error) => {
// console.log(error.message);
// });
const auth = getAuth();
signInWithPopup(auth, provider).then((res) => {
console.log(`ユーザー:${res.user}`);
}).catch((error) => {
console.log(error.message);
});
}
サインアウト
import { getAuth, GoogleAuthProvider, signInWithPopup, signOut } from "firebase/auth"; //v9
export const logOut = () => {
// firebase.auth().signOut().then((res) => {
// console.log(res.user);
// document.location.reload();
// }).catch((error) => {
// console.log(error.message);
// });
const auth = getAuth();
signOut(auth).then((res) => {
console.log(res.user);
document.location.reload();
}).catch((error) => {
console.log(error.message);
});
}