Skip to content

Instantly share code, notes, and snippets.

@GGrassiant
Last active December 26, 2020 21:50
Show Gist options
  • Select an option

  • Save GGrassiant/6d2a6c523ca587f68ac9f009a1fb78ce to your computer and use it in GitHub Desktop.

Select an option

Save GGrassiant/6d2a6c523ca587f68ac9f009a1fb78ce to your computer and use it in GitHub Desktop.
Firebase Real Time DB Call

Firebase Real Time DB Call

const App = () => {
const [stories, setStories] = useState<Array<StoryItem>>([]);
[...]
useEffect((): (() => void) => {
fetchStories(setStories);
return () => turnOffSubscription();
}, []);
...
// 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);
// 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();
}
// 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;
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