- switching from firestore to realtime DB

- implement debouncing tactic to sync data
- display sync indicator
This commit is contained in:
Amruth Pillai
2020-07-06 00:25:31 +05:30
parent 49a867dd37
commit 65fc779d58
15 changed files with 180 additions and 142 deletions
-81
View File
@@ -1,81 +0,0 @@
import firebase from "gatsby-plugin-firebase";
import React, { createContext, useContext, useEffect, useState } from "react";
import { v4 as uuidv4 } from "uuid";
import { transformCollectionSnapshot } from "../utils";
import UserContext from "./UserContext";
const defaultState = {
resumes: [],
createResume: async () => {},
deleteResume: async () => {},
};
const DashboardContext = createContext(defaultState);
const DashboardProvider = ({ children }) => {
const [resumes, setResumes] = useState([null]);
const [collectionRef, setCollectionRef] = useState(null);
const { user } = useContext(UserContext);
useEffect(() => {
if (user) {
setCollectionRef(`users/${user.uid}/resumes`);
}
}, [user]);
useEffect(() => {
if (collectionRef) {
firebase
.firestore()
.collection(collectionRef)
.onSnapshot((snapshot) =>
transformCollectionSnapshot(snapshot, setResumes)
);
}
}, [collectionRef]);
const createResume = async ({ name }) => {
const id = uuidv4();
const createdAt = firebase.firestore.FieldValue.serverTimestamp();
await firebase.firestore().collection(collectionRef).doc(id).set({
id,
name,
createdAt,
updatedAt: createdAt,
});
};
const updateResume = async (resume) => {
const { id, name } = resume;
if (resumes.find((x) => x.id === id) === resume) return;
await firebase.firestore().collection(collectionRef).doc(id).update({
id,
name,
updatedAt: firebase.firestore.FieldValue.serverTimestamp(),
});
};
const deleteResume = async (resume) => {
const { id } = resume;
await firebase.firestore().collection(collectionRef).doc(id).delete();
};
return (
<DashboardContext.Provider
value={{
resumes,
createResume,
updateResume,
deleteResume,
}}
>
{children}
</DashboardContext.Provider>
);
};
export default DashboardContext;
export { DashboardProvider };
+83
View File
@@ -0,0 +1,83 @@
import firebase from "gatsby-plugin-firebase";
import { debounce } from "lodash";
import React, { createContext, useContext, useState } from "react";
import { v4 as uuidv4 } from "uuid";
import UserContext from "./UserContext";
const defaultState = {
isUpdating: false,
getResume: async () => {},
createResume: () => {},
updateResume: async () => {},
deleteResume: () => {},
};
const DatabaseContext = createContext(defaultState);
const DatabaseProvider = ({ children }) => {
const [isUpdating, setUpdating] = useState(false);
const { user } = useContext(UserContext);
const getResume = async (id) => {
const snapshot = await firebase
.database()
.ref(`users/${user.uid}/resumes/${id}`)
.once("value");
return snapshot.val();
};
const createResume = (resume) => {
const id = uuidv4();
const createdAt = firebase.database.ServerValue.TIMESTAMP;
firebase
.database()
.ref(`users/${user.uid}/resumes/${id}`)
.set({
id,
...resume,
createdAt,
updatedAt: createdAt,
});
};
const updateResume = async (resume) => {
const { id } = resume;
setUpdating(true);
await firebase
.database()
.ref(`users/${user.uid}/resumes/${id}`)
.update({
...resume,
updatedAt: firebase.database.ServerValue.TIMESTAMP,
});
setUpdating(false);
};
const debouncedUpdate = debounce(updateResume, 2000);
const deleteResume = (id) => {
firebase.database().ref(`users/${user.uid}/resumes/${id}`).remove();
};
return (
<DatabaseContext.Provider
value={{
isUpdating,
getResume,
createResume,
updateResume: debouncedUpdate,
deleteResume,
}}
>
{children}
</DatabaseContext.Provider>
);
};
export default DatabaseContext;
export { DatabaseProvider };
+11 -15
View File
@@ -1,30 +1,26 @@
import { set } from "lodash";
import React, { createContext, useReducer } from "react";
import React, { createContext, useContext, useReducer } from "react";
import DatabaseContext from "./DatabaseContext";
const initialState = {
id: "dafa3242-f39a-4755-bab3-be3c3ca3d190",
profile: {
photograph: "",
firstName: "",
lastName: "",
},
createdAt: "",
updatedAt: "",
};
const ResumeContext = createContext(initialState);
const ResumeContext = createContext({});
const ResumeProvider = ({ children }) => {
const { updateResume } = useContext(DatabaseContext);
const [state, dispatch] = useReducer((state, { type, payload }) => {
let newState;
switch (type) {
case "on_input":
return set({ ...state }, payload.path, payload.value);
newState = set({ ...state }, payload.path, payload.value);
updateResume(newState);
return newState;
case "set_data":
return payload;
default:
throw new Error();
}
}, initialState);
}, {});
return (
<ResumeContext.Provider value={{ state, dispatch }}>
+6 -6
View File
@@ -1,8 +1,8 @@
import React, { createContext, useState, useEffect } from "react";
import { useAuthState } from "react-firebase-hooks/auth";
import firebase from "gatsby-plugin-firebase";
import { toast } from "react-toastify";
import { pick } from "lodash";
import React, { createContext, useEffect, useState } from "react";
import { useAuthState } from "react-firebase-hooks/auth";
import { toast } from "react-toastify";
const defaultUser = {
uid: null,
@@ -35,9 +35,9 @@ const UserProvider = ({ children }) => {
localStorage.setItem("user", JSON.stringify(user));
const addUserToDatabase = async () => {
const docRef = firebase.firestore().collection("users").doc(user.uid);
const snapshot = await docRef.get();
!snapshot.exists && docRef.set(user);
const userRef = firebase.database().ref(`users/${user.uid}`);
const snapshot = await userRef.once("value");
!snapshot.val() && userRef.set(user);
};
addUserToDatabase();