Learning Firebase to make CRUD, Authentication
React with TypeScript
Backend as Service
- Cloud Firestore
- Firebase ML
- Cloud Functions
- aws lambda와 같이 serverless funtion을 제공
- Cloud Storage
- aws s3와 같이 upload 기능을 제공
- Hosting
- Authentication
- Realtime Database
- Firebase original database
- Crashlytics
- Performance Monitoring
- Test Lab
- App Distribution
- 아이디어를 빠르게 실현하고 테스트하고 싶을 때
- DB, 회원가입 구현 등 쉽고 빠르다
- 실제 진지한 프로젝트에서는 사용하지 않는다
// for TypeScript
npx create-reate-app ohwitter --template typescript
// for Sass
yarn eject
rm -rf node_modules
yarn
yarn add node-sass sass-loader
// line 60 수정
const cssRegex = /\.(css|scss)$/;
const cssModuleRegex = /\.module\.(css|scss)$/;
// line 140 추가
{
loader: require.resolve("sass-loader"),
options: {
sourceMap: true
}
},
- Create Project
- Register app with platform
- npm install
npm install --save firebase
npm install --save @types/firebase
- Create Firebase file
// Firebase.ts
import firebase from "firebase/app";
import * as config from "./Config";
const firebaseConfig: object = {
apiKey: config.FIREBASE_API_KEY,
authDomain: config.FIREBASE_AUTH_DOMAIN,
projectId: config.FIREBASE_PROJECT_ID,
storageBucket: config.FIREBASE_STORAGE_BUCKET,
messagingSenderId: config.FIREBASE_MESSAGING_SENDER_ID,
appId: config.FIREBASE_APP_ID,
};
export default firebase.initializeApp(firebaseConfig);
// FBase.ts
import "firebase/auth";
...
export const authService: firebase.auth.Auth = firebase.auth();
// somewhere.tsx
import { authService } from "FBase";
// User | null
authService.currentUser;
const onSubmit = async (event: any) => {
event.preventDefault();
try {
if (newAccount) {
await authService.createUserWithEmailAndPassword(email, password);
} else {
await authService.signInWithEmailAndPassword(email, password);
}
} catch (error) {
console.log(error);
}
};
Value | Description |
---|---|
local (Default) | 브라우저가 닫혀도 상태가 유지됨. 상태 삭제를 원할 시 명시적으로 로그아웃해야함. |
session | 현재 세션, 탭에서만 상태가 유지됨. 인증된 탭이 닫힐 시 삭제됨. |
none | 상태가 메모리에만 저장됨. 활동이 새로고침되면 삭제됨. |
-
- eventListener 속성을 가지며 Firebase init, sign in, up, out시 trigger
useEffect(() => {
authService.onAuthStateChanged((user) => {
if (user) {
setIsLoggedIn(true);
} else {
setIsLoggedIn(false);
}
setInit(true);
});
}, []);
-
- provider을 생성, 사용하여 간단하게 구현 가능
const onClickSocial = async (
event: React.MouseEvent<HTMLButtonElement, MouseEvent>
) => {
const { name } = event.target as HTMLButtonElement;
let provider: any;
if (name === "google") {
provider = new firebaseInstance.auth.GoogleAuthProvider();
} else if (name === "github") {
provider = new firebaseInstance.auth.GithubAuthProvider();
}
await authService.signInWithPopup(provider);
};
// firebase.auth().signOut();
authService.signOut();
asia-northeast1 === Tokyo
asia-northeast2 === Osaka
asia-northeast3 === Seoul
import "firebase/firestore";
...
export const dbService: firebase.firestore.Firestore = firebase.firestore();
-
NoSQL
Collection
Documents
Collection
은Documents
의 그룹- Realtime
-
firebase.firestore().collection("COLLECTION NAME").add(SOMETHING)
const onSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
await dbService.collection("COLLECTION NAME").add({
// something you want
});
};
-
firebase.firestore().collection("COLLECTION NAME").get()
const getSomething = async () => {
const data: firebase.default.firestore.QuerySnapshot = await dbService
.collection("someCollection")
.get();
data.forEach((doc: firebase.default.firestore.QueryDocumentSnapshot) => {
const someObject = {
...doc.data(),
id: doc.id,
};
setSomething((prev) => [someObject, ...prev]);
});
};
authService.onAuthStateChanged((user) => {
console.log(user + "<<< This is your user !!");
});
-
- eventListener 속성을 가지며 해당 collection이 init, create, update, delete될 때를 감지
firebase.firestore().collection("COLLECTION NAME").onSnapshot()
dbService.collection("someCollection").onSnapshot((snapshot) => {
const someArray = snapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
// something you want
}));
setSomething(ohweetsArray);
});
-
firebase.firestore().doc("COLLECTION NAME/DOC ID").delete()
const onDelete = async () => {
const isOk = window.confirm("Are you sure?");
if (isOk) {
await dbService.doc(`someCollection/${someDoc.id}`).delete();
}
};
-
firebase.firestore().doc("COLLECTION NAME/DOC ID").update({updateTable: data})
const onUpdate = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
await dbService.doc(`someCollection/${someDoc.id}`).update({
text: newText,
});
setIsEdit(false);
};
import "firebase/storage";
...
export const storageService: firebase.storage.Storage = firebase.storage();
// storageService.ref().child("REFERENCE NAME/FILE NAME")
const fileRef = storageService.ref().child(`${userObj?.uid}/${uuid()}`);
// fileRef.putString(file data, data classification);
const response = await fileRef.putString("FILE URL", "data_url");
fileURL = await response.ref.getDownloadURL();
await storageService.refFromURL(obj.fileURL).delete();
-
- where을 이용하여 필터링 가능
const func = async () => {
const datas = await dbService
.collection("COLLECTION_NAME")
.where("something", "==", someObj?.uid)
.get();
};
const datas = await dbService
.collection("COLLECTION_NAME")
.where("something", "==", someObj?.uid)
.orderBy("createdAt", "desc");
// or .orderBy("createdAt", "asc");
-
- error에 나온 url을 이용하여 index를 생성하여 사용 가능
const func = async () => {
const datas = await dbService
.collection("COLLECTION_NAME")
.where("something", "==", someObj?.uid)
.orderBy("createdAt")
.get();
};
-
- firestore에 user collection을 이용하면 기본적으로 제공되는 authentication외의 다양한 정보를 저장, 사용 가능
-
- firebase의 updateProfile method는 displayName, photoUrl만 변경이 가능
await userObj?.updateProfile({
displayName: newName,
photoURL: someURL,
});