Firebase Real Time DB Call
Last active
December 26, 2020 21:50
-
-
Save GGrassiant/6d2a6c523ca587f68ac9f009a1fb78ce to your computer and use it in GitHub Desktop.
Firebase Real Time DB Call
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const App = () => { | |
| const [stories, setStories] = useState<Array<StoryItem>>([]); | |
| [...] | |
| useEffect((): (() => void) => { | |
| fetchStories(setStories); | |
| return () => turnOffSubscription(); | |
| }, []); | |
| ... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Libs | |
| import * as firebase from 'firebase/app'; | |
| import 'firebase/database'; | |
| const config = { | |
| authDomain: 'hacker-news.firebaseio.com', | |
| databaseURL: 'https://hacker-news.firebaseio.com', | |
| }; | |
| export default firebase.initializeApp(config); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Libs | |
| import firebase from "firebase/app"; | |
| import "firebase/auth"; | |
| import "firebase/firestore"; | |
| import "firebase/storage"; | |
| import axios from 'axios'; | |
| // Config | |
| const firebaseConfig = { | |
| apiKey: import.meta.env.VITE_API_KEY, | |
| authDomain: import.meta.env.VITE_AUTH_DOMAIN, | |
| databaseURL: import.meta.env.VITE_DATABASE_URL, | |
| projectId: import.meta.env.VITE_PROJECT_ID, | |
| storageBucket: import.meta.env.VITE_STORAGE_BUCKET, | |
| messagingSenderId: import.meta.env.VITE_MESSAGING_SENDER_ID, | |
| appId: import.meta.env.VITE_APP_ID, | |
| measurementId: import.meta.env.VITE_MEASUREMENT_ID | |
| }; | |
| // Utils | |
| const firebaseApp = !firebase.apps.length | |
| ? firebase.initializeApp(firebaseConfig) | |
| : firebase.app(); | |
| const db = firebaseApp.firestore(); | |
| const auth = firebaseApp.auth(); | |
| const storage = firebaseApp.storage(); | |
| // Helper Functions | |
| // AUTH // | |
| export function checkAuth(callBack) { | |
| return auth.onAuthStateChanged(callBack); | |
| } | |
| export async function signInWithGoogle() { | |
| const provider = new firebase.auth.GoogleAuthProvider(); | |
| await auth.signInWithPopup(provider); | |
| window.location.reload(); | |
| } | |
| export async function logOut() { | |
| await auth.signOut(); | |
| window.location.reload(); | |
| } | |
| // COLLECTIONS // | |
| export async function getCollection(id) { | |
| const snapshot = await db.collection(id).get(); | |
| return snapshot | |
| .docs | |
| .map(doc => ({ id: doc.id, ...doc.data() })); | |
| } | |
| export async function getUserLists(userId) { | |
| const snapshot = await db.collection('lists') | |
| .where('userIds', 'array-contains', userId) | |
| .get(); | |
| return snapshot | |
| .docs | |
| .map(doc => ({ id: doc.id, ...doc.data() })); | |
| } | |
| function uploadCoverImage(file) { | |
| const uploadTask = storage | |
| .ref(`image/${file.name}-${file.lastModified}`) | |
| .put(file); | |
| return new Promise((resolve, reject) =>{ | |
| uploadTask.on('state_changed', | |
| (snapshot) => console.log('image uploading', snapshot), | |
| reject, | |
| () => { | |
| storage.ref(`image/${file.name}-${file.lastModified}`) | |
| .getDownloadURL() | |
| .then(resolve); | |
| } | |
| ); | |
| }); | |
| } | |
| export async function createList(list, user) { | |
| const { name, description, image } = list; | |
| await db.collection('lists').add({ | |
| name, | |
| description, | |
| image: image ? await uploadCoverImage(image) : null, | |
| created: firebase.firestore.FieldValue.serverTimestamp(), | |
| author: user.uid, | |
| userIds: [user.uid], | |
| users: [ | |
| { | |
| id: user.uid, | |
| name: user.displayName, | |
| } | |
| ] | |
| }) | |
| } | |
| export async function getList(listId) { | |
| try { | |
| const list = await db.collection('lists') | |
| .doc(listId) | |
| .get(); | |
| if(!list.exists) throw Error('List does not exist'); | |
| return list.data(); | |
| } catch (error) { | |
| console.error(error); | |
| throw Error(error); | |
| } | |
| } | |
| export async function createListItem({ user, listId, item }) { | |
| try { | |
| const { data }= await axios({ | |
| method: 'post', | |
| url: `https://screenshotapi.net/api/v1/screenshot?url=${item.link}&token=${import.meta.env.VITE_SCREENSHOT_API_KEY}`, | |
| }); | |
| const { screenshot } = data; | |
| await db.collection('lists') | |
| .doc(listId) | |
| .collection('items') | |
| .add({ | |
| name: item.name, | |
| link: item.link, | |
| image: screenshot, | |
| created: firebase.firestore.FieldValue.serverTimestamp(), | |
| author: { | |
| id: user.uid, | |
| name: user.displayName, | |
| } | |
| }); | |
| } catch (error) { | |
| console.error(error); | |
| throw new Error(error); | |
| } | |
| } | |
| // REALTIME // | |
| export function subscribeToListItems(listId, cb) { | |
| return db.collection('lists') | |
| .doc(listId) | |
| .collection('items') | |
| .orderBy('created', 'desc') | |
| .onSnapshot(cb); | |
| } | |
| export function deleteListItem(listId, itemId) { | |
| return db.collection('lists') | |
| .doc(listId) | |
| .collection('items') | |
| .doc(itemId) | |
| .delete(); | |
| } | |
| // JOINT LISTS // | |
| export async function addUserToList(user, listId) { | |
| await db.collection('lists') | |
| .doc(listId) | |
| .update({ | |
| userIds: firebase.firestore.FieldValue.arrayUnion(user.uid), | |
| users: firebase.firestore.FieldValue.arrayUnion({ | |
| id: user.uid, | |
| name: user.displayName, | |
| }) | |
| }); | |
| window.location.reload(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Libs | |
| import db from './db'; | |
| // Utils | |
| import { StoryItem } from '../components/Story'; | |
| const findStory = (storyId: string | null) => | |
| db | |
| .database() | |
| .ref(`v0/item/${storyId}`) | |
| .once('value') | |
| .then((snapshot) => snapshot.val()); | |
| export const fetchStories = (setStories: (arg: Array<StoryItem>) => void) => { | |
| const arrayOfPromises: Array<Promise<StoryItem>> = []; | |
| let story; | |
| db.database() | |
| .ref('v0/topstories') | |
| .on('value', (snapshot) => { | |
| snapshot.forEach((storySnapShot) => { | |
| story = findStory(storySnapShot.val()); | |
| arrayOfPromises.push(story); | |
| }); | |
| return Promise.all(arrayOfPromises) | |
| .then((arrayOfStories) => { | |
| setStories(arrayOfStories); | |
| }) | |
| .catch((error) => { | |
| console.log(error); | |
| throw new Error(error); | |
| }); | |
| }); | |
| }; | |
| export const turnOffSubscription = () => db.database().ref('v0/topstories').off; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { mutate } from "swr"; | |
| const handleCreateList = async () => { | |
| setSubmitting(true); | |
| try { | |
| await db.createList(list, user); | |
| // need to mutate the userId to see live refetching of data in List | |
| // since we call const { data: lists, error } = useSWR(user.uid, db.getUserLists); | |
| await mutate(user.uid); | |
| setList(DEFAULT_LIST); | |
| } catch (error) { | |
| console.log(error); | |
| } finally { | |
| setSubmitting(false); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment