Add Firebase schema collection helpers (kind of an RFC) (#583)
* Add Firebase schema collection helpers * Decentralize definitions from schema file (James feedback) * Add lint comment
This commit is contained in:
parent
8132fa595b
commit
3b4666ba3e
|
@ -2,16 +2,16 @@ import { useEffect } from 'react'
|
|||
import { useFirestoreDocumentData } from '@react-query-firebase/firestore'
|
||||
import {
|
||||
Contract,
|
||||
contractDocRef,
|
||||
contracts,
|
||||
listenForContract,
|
||||
} from 'web/lib/firebase/contracts'
|
||||
import { useStateCheckEquality } from './use-state-check-equality'
|
||||
import { DocumentData } from 'firebase/firestore'
|
||||
import { doc, DocumentData } from 'firebase/firestore'
|
||||
|
||||
export const useContract = (contractId: string) => {
|
||||
const result = useFirestoreDocumentData<DocumentData, Contract>(
|
||||
['contracts', contractId],
|
||||
contractDocRef(contractId),
|
||||
doc(contracts, contractId),
|
||||
{ subscribe: true, includeMetadataChanges: true }
|
||||
)
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'
|
|||
import { useFirestoreDocumentData } from '@react-query-firebase/firestore'
|
||||
import { QueryClient } from 'react-query'
|
||||
|
||||
import { DocumentData } from 'firebase/firestore'
|
||||
import { doc, DocumentData } from 'firebase/firestore'
|
||||
import { PrivateUser } from 'common/user'
|
||||
import {
|
||||
getUser,
|
||||
|
@ -10,7 +10,7 @@ import {
|
|||
listenForPrivateUser,
|
||||
listenForUser,
|
||||
User,
|
||||
userDocRef,
|
||||
users,
|
||||
} from 'web/lib/firebase/users'
|
||||
import { useStateCheckEquality } from './use-state-check-equality'
|
||||
import { identifyUser, setUserProperty } from 'web/lib/service/analytics'
|
||||
|
@ -49,7 +49,7 @@ export const usePrivateUser = (userId?: string) => {
|
|||
export const useUserById = (userId: string) => {
|
||||
const result = useFirestoreDocumentData<DocumentData, User>(
|
||||
['users', userId],
|
||||
userDocRef(userId),
|
||||
doc(users, userId),
|
||||
{ subscribe: true, includeMetadataChanges: true }
|
||||
)
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import dayjs from 'dayjs'
|
||||
import {
|
||||
getFirestore,
|
||||
doc,
|
||||
setDoc,
|
||||
deleteDoc,
|
||||
|
@ -16,8 +15,7 @@ import {
|
|||
} from 'firebase/firestore'
|
||||
import { sortBy, sum } from 'lodash'
|
||||
|
||||
import { app } from './init'
|
||||
import { getValues, listenForValue, listenForValues } from './utils'
|
||||
import { coll, getValues, listenForValue, listenForValues } from './utils'
|
||||
import { BinaryContract, Contract } from 'common/contract'
|
||||
import { getDpmProbability } from 'common/calculate-dpm'
|
||||
import { createRNG, shuffle } from 'common/util/random'
|
||||
|
@ -28,6 +26,9 @@ import { MAX_FEED_CONTRACTS } from 'common/recommended-contracts'
|
|||
import { Bet } from 'common/bet'
|
||||
import { Comment } from 'common/comment'
|
||||
import { ENV_CONFIG } from 'common/envs/constants'
|
||||
|
||||
export const contracts = coll<Contract>('contracts')
|
||||
|
||||
export type { Contract }
|
||||
|
||||
export function contractPath(contract: Contract) {
|
||||
|
@ -86,83 +87,72 @@ export function tradingAllowed(contract: Contract) {
|
|||
)
|
||||
}
|
||||
|
||||
const db = getFirestore(app)
|
||||
export const contractCollection = collection(db, 'contracts')
|
||||
export const contractDocRef = (contractId: string) =>
|
||||
doc(db, 'contracts', contractId)
|
||||
|
||||
// Push contract to Firestore
|
||||
export async function setContract(contract: Contract) {
|
||||
const docRef = doc(db, 'contracts', contract.id)
|
||||
await setDoc(docRef, contract)
|
||||
await setDoc(doc(contracts, contract.id), contract)
|
||||
}
|
||||
|
||||
export async function updateContract(
|
||||
contractId: string,
|
||||
update: Partial<Contract>
|
||||
) {
|
||||
const docRef = doc(db, 'contracts', contractId)
|
||||
await updateDoc(docRef, update)
|
||||
await updateDoc(doc(contracts, contractId), update)
|
||||
}
|
||||
|
||||
export async function getContractFromId(contractId: string) {
|
||||
const docRef = doc(db, 'contracts', contractId)
|
||||
const result = await getDoc(docRef)
|
||||
|
||||
return result.exists() ? (result.data() as Contract) : undefined
|
||||
const result = await getDoc(doc(contracts, contractId))
|
||||
return result.exists() ? result.data() : undefined
|
||||
}
|
||||
|
||||
export async function getContractFromSlug(slug: string) {
|
||||
const q = query(contractCollection, where('slug', '==', slug))
|
||||
const q = query(contracts, where('slug', '==', slug))
|
||||
const snapshot = await getDocs(q)
|
||||
|
||||
return snapshot.empty ? undefined : (snapshot.docs[0].data() as Contract)
|
||||
return snapshot.empty ? undefined : snapshot.docs[0].data()
|
||||
}
|
||||
|
||||
export async function deleteContract(contractId: string) {
|
||||
const docRef = doc(db, 'contracts', contractId)
|
||||
await deleteDoc(docRef)
|
||||
await deleteDoc(doc(contracts, contractId))
|
||||
}
|
||||
|
||||
export async function listContracts(creatorId: string): Promise<Contract[]> {
|
||||
const q = query(
|
||||
contractCollection,
|
||||
contracts,
|
||||
where('creatorId', '==', creatorId),
|
||||
orderBy('createdTime', 'desc')
|
||||
)
|
||||
const snapshot = await getDocs(q)
|
||||
return snapshot.docs.map((doc) => doc.data() as Contract)
|
||||
return snapshot.docs.map((doc) => doc.data())
|
||||
}
|
||||
|
||||
export async function listTaggedContractsCaseInsensitive(
|
||||
tag: string
|
||||
): Promise<Contract[]> {
|
||||
const q = query(
|
||||
contractCollection,
|
||||
contracts,
|
||||
where('lowercaseTags', 'array-contains', tag.toLowerCase()),
|
||||
orderBy('createdTime', 'desc')
|
||||
)
|
||||
const snapshot = await getDocs(q)
|
||||
return snapshot.docs.map((doc) => doc.data() as Contract)
|
||||
return snapshot.docs.map((doc) => doc.data())
|
||||
}
|
||||
|
||||
export async function listAllContracts(
|
||||
n: number,
|
||||
before?: string
|
||||
): Promise<Contract[]> {
|
||||
let q = query(contractCollection, orderBy('createdTime', 'desc'), limit(n))
|
||||
let q = query(contracts, orderBy('createdTime', 'desc'), limit(n))
|
||||
if (before != null) {
|
||||
const snap = await getDoc(doc(db, 'contracts', before))
|
||||
const snap = await getDoc(doc(contracts, before))
|
||||
q = query(q, startAfter(snap))
|
||||
}
|
||||
const snapshot = await getDocs(q)
|
||||
return snapshot.docs.map((doc) => doc.data() as Contract)
|
||||
return snapshot.docs.map((doc) => doc.data())
|
||||
}
|
||||
|
||||
export function listenForContracts(
|
||||
setContracts: (contracts: Contract[]) => void
|
||||
) {
|
||||
const q = query(contractCollection, orderBy('createdTime', 'desc'))
|
||||
const q = query(contracts, orderBy('createdTime', 'desc'))
|
||||
return listenForValues<Contract>(q, setContracts)
|
||||
}
|
||||
|
||||
|
@ -171,7 +161,7 @@ export function listenForUserContracts(
|
|||
setContracts: (contracts: Contract[]) => void
|
||||
) {
|
||||
const q = query(
|
||||
contractCollection,
|
||||
contracts,
|
||||
where('creatorId', '==', creatorId),
|
||||
orderBy('createdTime', 'desc')
|
||||
)
|
||||
|
@ -179,7 +169,7 @@ export function listenForUserContracts(
|
|||
}
|
||||
|
||||
const activeContractsQuery = query(
|
||||
contractCollection,
|
||||
contracts,
|
||||
where('isResolved', '==', false),
|
||||
where('visibility', '==', 'public'),
|
||||
where('volume7Days', '>', 0)
|
||||
|
@ -196,7 +186,7 @@ export function listenForActiveContracts(
|
|||
}
|
||||
|
||||
const inactiveContractsQuery = query(
|
||||
contractCollection,
|
||||
contracts,
|
||||
where('isResolved', '==', false),
|
||||
where('closeTime', '>', Date.now()),
|
||||
where('visibility', '==', 'public'),
|
||||
|
@ -214,7 +204,7 @@ export function listenForInactiveContracts(
|
|||
}
|
||||
|
||||
const newContractsQuery = query(
|
||||
contractCollection,
|
||||
contracts,
|
||||
where('isResolved', '==', false),
|
||||
where('volume7Days', '==', 0),
|
||||
where('createdTime', '>', Date.now() - 7 * DAY_MS)
|
||||
|
@ -230,7 +220,7 @@ export function listenForContract(
|
|||
contractId: string,
|
||||
setContract: (contract: Contract | null) => void
|
||||
) {
|
||||
const contractRef = doc(contractCollection, contractId)
|
||||
const contractRef = doc(contracts, contractId)
|
||||
return listenForValue<Contract>(contractRef, setContract)
|
||||
}
|
||||
|
||||
|
@ -242,7 +232,7 @@ function chooseRandomSubset(contracts: Contract[], count: number) {
|
|||
}
|
||||
|
||||
const hotContractsQuery = query(
|
||||
contractCollection,
|
||||
contracts,
|
||||
where('isResolved', '==', false),
|
||||
where('visibility', '==', 'public'),
|
||||
orderBy('volume24Hours', 'desc'),
|
||||
|
@ -262,22 +252,22 @@ export function listenForHotContracts(
|
|||
}
|
||||
|
||||
export async function getHotContracts() {
|
||||
const contracts = await getValues<Contract>(hotContractsQuery)
|
||||
const data = await getValues<Contract>(hotContractsQuery)
|
||||
return sortBy(
|
||||
chooseRandomSubset(contracts, 10),
|
||||
chooseRandomSubset(data, 10),
|
||||
(contract) => -1 * contract.volume24Hours
|
||||
)
|
||||
}
|
||||
|
||||
export async function getContractsBySlugs(slugs: string[]) {
|
||||
const q = query(contractCollection, where('slug', 'in', slugs))
|
||||
const q = query(contracts, where('slug', 'in', slugs))
|
||||
const snapshot = await getDocs(q)
|
||||
const contracts = snapshot.docs.map((doc) => doc.data() as Contract)
|
||||
return sortBy(contracts, (contract) => -1 * contract.volume24Hours)
|
||||
const data = snapshot.docs.map((doc) => doc.data())
|
||||
return sortBy(data, (contract) => -1 * contract.volume24Hours)
|
||||
}
|
||||
|
||||
const topWeeklyQuery = query(
|
||||
contractCollection,
|
||||
contracts,
|
||||
where('isResolved', '==', false),
|
||||
orderBy('volume7Days', 'desc'),
|
||||
limit(MAX_FEED_CONTRACTS)
|
||||
|
@ -287,7 +277,7 @@ export async function getTopWeeklyContracts() {
|
|||
}
|
||||
|
||||
const closingSoonQuery = query(
|
||||
contractCollection,
|
||||
contracts,
|
||||
where('isResolved', '==', false),
|
||||
where('visibility', '==', 'public'),
|
||||
where('closeTime', '>', Date.now()),
|
||||
|
@ -296,15 +286,12 @@ const closingSoonQuery = query(
|
|||
)
|
||||
|
||||
export async function getClosingSoonContracts() {
|
||||
const contracts = await getValues<Contract>(closingSoonQuery)
|
||||
return sortBy(
|
||||
chooseRandomSubset(contracts, 2),
|
||||
(contract) => contract.closeTime
|
||||
)
|
||||
const data = await getValues<Contract>(closingSoonQuery)
|
||||
return sortBy(chooseRandomSubset(data, 2), (contract) => contract.closeTime)
|
||||
}
|
||||
|
||||
export async function getRecentBetsAndComments(contract: Contract) {
|
||||
const contractDoc = doc(db, 'contracts', contract.id)
|
||||
const contractDoc = doc(contracts, contract.id)
|
||||
|
||||
const [recentBets, recentComments] = await Promise.all([
|
||||
getValues<Bet>(
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {
|
||||
collection,
|
||||
deleteDoc,
|
||||
doc,
|
||||
getDocs,
|
||||
query,
|
||||
updateDoc,
|
||||
where,
|
||||
|
@ -9,11 +9,16 @@ import {
|
|||
import { sortBy } from 'lodash'
|
||||
import { Group } from 'common/group'
|
||||
import { getContractFromId } from './contracts'
|
||||
import { db } from './init'
|
||||
import { getValue, getValues, listenForValue, listenForValues } from './utils'
|
||||
import {
|
||||
coll,
|
||||
getValue,
|
||||
getValues,
|
||||
listenForValue,
|
||||
listenForValues,
|
||||
} from './utils'
|
||||
import { filterDefined } from 'common/util/array'
|
||||
|
||||
const groupCollection = collection(db, 'groups')
|
||||
export const groups = coll<Group>('groups')
|
||||
|
||||
export function groupPath(
|
||||
groupSlug: string,
|
||||
|
@ -23,30 +28,29 @@ export function groupPath(
|
|||
}
|
||||
|
||||
export function updateGroup(group: Group, updates: Partial<Group>) {
|
||||
return updateDoc(doc(groupCollection, group.id), updates)
|
||||
return updateDoc(doc(groups, group.id), updates)
|
||||
}
|
||||
|
||||
export function deleteGroup(group: Group) {
|
||||
return deleteDoc(doc(groupCollection, group.id))
|
||||
return deleteDoc(doc(groups, group.id))
|
||||
}
|
||||
|
||||
export async function listAllGroups() {
|
||||
return getValues<Group>(groupCollection)
|
||||
return getValues<Group>(groups)
|
||||
}
|
||||
|
||||
export function listenForGroups(setGroups: (groups: Group[]) => void) {
|
||||
return listenForValues(groupCollection, setGroups)
|
||||
return listenForValues(groups, setGroups)
|
||||
}
|
||||
|
||||
export function getGroup(groupId: string) {
|
||||
return getValue<Group>(doc(groupCollection, groupId))
|
||||
return getValue<Group>(doc(groups, groupId))
|
||||
}
|
||||
|
||||
export async function getGroupBySlug(slug: string) {
|
||||
const q = query(groupCollection, where('slug', '==', slug))
|
||||
const groups = await getValues<Group>(q)
|
||||
|
||||
return groups.length === 0 ? null : groups[0]
|
||||
const q = query(groups, where('slug', '==', slug))
|
||||
const docs = (await getDocs(q)).docs
|
||||
return docs.length === 0 ? null : docs[0].data()
|
||||
}
|
||||
|
||||
export async function getGroupContracts(group: Group) {
|
||||
|
@ -68,14 +72,14 @@ export function listenForGroup(
|
|||
groupId: string,
|
||||
setGroup: (group: Group | null) => void
|
||||
) {
|
||||
return listenForValue(doc(groupCollection, groupId), setGroup)
|
||||
return listenForValue(doc(groups, groupId), setGroup)
|
||||
}
|
||||
|
||||
export function listenForMemberGroups(
|
||||
userId: string,
|
||||
setGroups: (groups: Group[]) => void
|
||||
) {
|
||||
const q = query(groupCollection, where('memberIds', 'array-contains', userId))
|
||||
const q = query(groups, where('memberIds', 'array-contains', userId))
|
||||
|
||||
return listenForValues<Group>(q, (groups) => {
|
||||
const sorted = sortBy(groups, [(group) => -group.mostRecentActivityTime])
|
||||
|
@ -87,12 +91,8 @@ export async function getGroupsWithContractId(
|
|||
contractId: string,
|
||||
setGroups: (groups: Group[]) => void
|
||||
) {
|
||||
const q = query(
|
||||
groupCollection,
|
||||
where('contractIds', 'array-contains', contractId)
|
||||
)
|
||||
const groups = await getValues<Group>(q)
|
||||
setGroups(groups)
|
||||
const q = query(groups, where('contractIds', 'array-contains', contractId))
|
||||
setGroups(await getValues<Group>(q))
|
||||
}
|
||||
|
||||
export async function joinGroup(group: Group, userId: string): Promise<Group> {
|
||||
|
|
|
@ -1,18 +1,12 @@
|
|||
import {
|
||||
collection,
|
||||
getDoc,
|
||||
orderBy,
|
||||
query,
|
||||
setDoc,
|
||||
where,
|
||||
} from 'firebase/firestore'
|
||||
import { getDoc, orderBy, query, setDoc, where } from 'firebase/firestore'
|
||||
import { doc } from 'firebase/firestore'
|
||||
import { Manalink } from '../../../common/manalink'
|
||||
import { db } from './init'
|
||||
import { customAlphabet } from 'nanoid'
|
||||
import { listenForValues } from './utils'
|
||||
import { coll, listenForValues } from './utils'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
export const manalinks = coll<Manalink>('manalinks')
|
||||
|
||||
export async function createManalink(data: {
|
||||
fromId: string
|
||||
amount: number
|
||||
|
@ -45,29 +39,25 @@ export async function createManalink(data: {
|
|||
message,
|
||||
}
|
||||
|
||||
const ref = doc(db, 'manalinks', slug)
|
||||
await setDoc(ref, manalink)
|
||||
await setDoc(doc(manalinks, slug), manalink)
|
||||
return slug
|
||||
}
|
||||
|
||||
const manalinkCol = collection(db, 'manalinks')
|
||||
|
||||
// TODO: This required an index, make sure to also set up in prod
|
||||
function listUserManalinks(fromId?: string) {
|
||||
return query(
|
||||
manalinkCol,
|
||||
manalinks,
|
||||
where('fromId', '==', fromId),
|
||||
orderBy('createdTime', 'desc')
|
||||
)
|
||||
}
|
||||
|
||||
export async function getManalink(slug: string) {
|
||||
const docSnap = await getDoc(doc(db, 'manalinks', slug))
|
||||
return docSnap.data() as Manalink
|
||||
return (await getDoc(doc(manalinks, slug))).data()
|
||||
}
|
||||
|
||||
export function useManalink(slug: string) {
|
||||
const [manalink, setManalink] = useState<Manalink | null>(null)
|
||||
const [manalink, setManalink] = useState<Manalink | undefined>(undefined)
|
||||
useEffect(() => {
|
||||
if (slug) {
|
||||
getManalink(slug).then(setManalink)
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
import { ManalinkTxn, DonationTxn, TipTxn } from 'common/txn'
|
||||
import { collection, orderBy, query, where } from 'firebase/firestore'
|
||||
import { db } from './init'
|
||||
import { getValues, listenForValues } from './utils'
|
||||
import { ManalinkTxn, DonationTxn, TipTxn, Txn } from 'common/txn'
|
||||
import { orderBy, query, where } from 'firebase/firestore'
|
||||
import { coll, getValues, listenForValues } from './utils'
|
||||
import { useState, useEffect } from 'react'
|
||||
import { orderBy as _orderBy } from 'lodash'
|
||||
|
||||
const txnCollection = collection(db, 'txns')
|
||||
export const txns = coll<Txn>('txns')
|
||||
|
||||
const getCharityQuery = (charityId: string) =>
|
||||
query(
|
||||
txnCollection,
|
||||
txns,
|
||||
where('toType', '==', 'CHARITY'),
|
||||
where('toId', '==', charityId),
|
||||
orderBy('createdTime', 'desc')
|
||||
|
@ -22,7 +21,7 @@ export function listenForCharityTxns(
|
|||
return listenForValues<DonationTxn>(getCharityQuery(charityId), setTxns)
|
||||
}
|
||||
|
||||
const charitiesQuery = query(txnCollection, where('toType', '==', 'CHARITY'))
|
||||
const charitiesQuery = query(txns, where('toType', '==', 'CHARITY'))
|
||||
|
||||
export function getAllCharityTxns() {
|
||||
return getValues<DonationTxn>(charitiesQuery)
|
||||
|
@ -30,7 +29,7 @@ export function getAllCharityTxns() {
|
|||
|
||||
const getTipsQuery = (contractId: string) =>
|
||||
query(
|
||||
txnCollection,
|
||||
txns,
|
||||
where('category', '==', 'TIP'),
|
||||
where('data.contractId', '==', contractId)
|
||||
)
|
||||
|
@ -50,13 +49,13 @@ export function useManalinkTxns(userId: string) {
|
|||
useEffect(() => {
|
||||
// TODO: Need to instantiate these indexes too
|
||||
const fromQuery = query(
|
||||
txnCollection,
|
||||
txns,
|
||||
where('fromId', '==', userId),
|
||||
where('category', '==', 'MANALINK'),
|
||||
orderBy('createdTime', 'desc')
|
||||
)
|
||||
const toQuery = query(
|
||||
txnCollection,
|
||||
txns,
|
||||
where('toId', '==', userId),
|
||||
where('category', '==', 'MANALINK'),
|
||||
orderBy('createdTime', 'desc')
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import {
|
||||
getFirestore,
|
||||
doc,
|
||||
setDoc,
|
||||
getDoc,
|
||||
|
@ -23,58 +22,62 @@ import {
|
|||
} from 'firebase/auth'
|
||||
import { throttle, zip } from 'lodash'
|
||||
|
||||
import { app } from './init'
|
||||
import { app, db } from './init'
|
||||
import { PortfolioMetrics, PrivateUser, User } from 'common/user'
|
||||
import { createUser } from './fn-call'
|
||||
import { getValue, getValues, listenForValue, listenForValues } from './utils'
|
||||
import {
|
||||
coll,
|
||||
getValue,
|
||||
getValues,
|
||||
listenForValue,
|
||||
listenForValues,
|
||||
} from './utils'
|
||||
import { feed } from 'common/feed'
|
||||
import { CATEGORY_LIST } from 'common/categories'
|
||||
import { safeLocalStorage } from '../util/local'
|
||||
import { filterDefined } from 'common/util/array'
|
||||
|
||||
export const users = coll<User>('users')
|
||||
export const privateUsers = coll<PrivateUser>('private-users')
|
||||
|
||||
export type { User }
|
||||
|
||||
export type Period = 'daily' | 'weekly' | 'monthly' | 'allTime'
|
||||
|
||||
const db = getFirestore(app)
|
||||
export const auth = getAuth(app)
|
||||
|
||||
export const userDocRef = (userId: string) => doc(db, 'users', userId)
|
||||
|
||||
export async function getUser(userId: string) {
|
||||
const docSnap = await getDoc(userDocRef(userId))
|
||||
return docSnap.data() as User
|
||||
/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */
|
||||
return (await getDoc(doc(users, userId))).data()!
|
||||
}
|
||||
|
||||
export async function getUserByUsername(username: string) {
|
||||
// Find a user whose username matches the given username, or null if no such user exists.
|
||||
const userCollection = collection(db, 'users')
|
||||
const q = query(userCollection, where('username', '==', username), limit(1))
|
||||
const docs = await getDocs(q)
|
||||
const users = docs.docs.map((doc) => doc.data() as User)
|
||||
return users[0] || null
|
||||
const q = query(users, where('username', '==', username), limit(1))
|
||||
const docs = (await getDocs(q)).docs
|
||||
return docs.length > 0 ? docs[0].data() : null
|
||||
}
|
||||
|
||||
export async function setUser(userId: string, user: User) {
|
||||
await setDoc(doc(db, 'users', userId), user)
|
||||
await setDoc(doc(users, userId), user)
|
||||
}
|
||||
|
||||
export async function updateUser(userId: string, update: Partial<User>) {
|
||||
await updateDoc(doc(db, 'users', userId), { ...update })
|
||||
await updateDoc(doc(users, userId), { ...update })
|
||||
}
|
||||
|
||||
export async function updatePrivateUser(
|
||||
userId: string,
|
||||
update: Partial<PrivateUser>
|
||||
) {
|
||||
await updateDoc(doc(db, 'private-users', userId), { ...update })
|
||||
await updateDoc(doc(privateUsers, userId), { ...update })
|
||||
}
|
||||
|
||||
export function listenForUser(
|
||||
userId: string,
|
||||
setUser: (user: User | null) => void
|
||||
) {
|
||||
const userRef = doc(db, 'users', userId)
|
||||
const userRef = doc(users, userId)
|
||||
return listenForValue<User>(userRef, setUser)
|
||||
}
|
||||
|
||||
|
@ -82,7 +85,7 @@ export function listenForPrivateUser(
|
|||
userId: string,
|
||||
setPrivateUser: (privateUser: PrivateUser | null) => void
|
||||
) {
|
||||
const userRef = doc(db, 'private-users', userId)
|
||||
const userRef = doc(privateUsers, userId)
|
||||
return listenForValue<PrivateUser>(userRef, setPrivateUser)
|
||||
}
|
||||
|
||||
|
@ -152,36 +155,29 @@ export async function listUsers(userIds: string[]) {
|
|||
if (userIds.length > 10) {
|
||||
throw new Error('Too many users requested at once; Firestore limits to 10')
|
||||
}
|
||||
const userCollection = collection(db, 'users')
|
||||
const q = query(userCollection, where('id', 'in', userIds))
|
||||
const docs = await getDocs(q)
|
||||
return docs.docs.map((doc) => doc.data() as User)
|
||||
const q = query(users, where('id', 'in', userIds))
|
||||
const docs = (await getDocs(q)).docs
|
||||
return docs.map((doc) => doc.data())
|
||||
}
|
||||
|
||||
export async function listAllUsers() {
|
||||
const userCollection = collection(db, 'users')
|
||||
const q = query(userCollection)
|
||||
const docs = await getDocs(q)
|
||||
return docs.docs.map((doc) => doc.data() as User)
|
||||
const docs = (await getDocs(users)).docs
|
||||
return docs.map((doc) => doc.data())
|
||||
}
|
||||
|
||||
export function listenForAllUsers(setUsers: (users: User[]) => void) {
|
||||
const userCollection = collection(db, 'users')
|
||||
const q = query(userCollection)
|
||||
listenForValues(q, setUsers)
|
||||
listenForValues(users, setUsers)
|
||||
}
|
||||
|
||||
export function listenForPrivateUsers(
|
||||
setUsers: (users: PrivateUser[]) => void
|
||||
) {
|
||||
const userCollection = collection(db, 'private-users')
|
||||
const q = query(userCollection)
|
||||
listenForValues(q, setUsers)
|
||||
listenForValues(privateUsers, setUsers)
|
||||
}
|
||||
|
||||
export function getTopTraders(period: Period) {
|
||||
const topTraders = query(
|
||||
collection(db, 'users'),
|
||||
users,
|
||||
orderBy('profitCached.' + period, 'desc'),
|
||||
limit(20)
|
||||
)
|
||||
|
@ -191,7 +187,7 @@ export function getTopTraders(period: Period) {
|
|||
|
||||
export function getTopCreators(period: Period) {
|
||||
const topCreators = query(
|
||||
collection(db, 'users'),
|
||||
users,
|
||||
orderBy('creatorVolumeCached.' + period, 'desc'),
|
||||
limit(20)
|
||||
)
|
||||
|
@ -199,22 +195,21 @@ export function getTopCreators(period: Period) {
|
|||
}
|
||||
|
||||
export async function getTopFollowed() {
|
||||
const users = await getValues<User>(topFollowedQuery)
|
||||
return users.slice(0, 20)
|
||||
return (await getValues<User>(topFollowedQuery)).slice(0, 20)
|
||||
}
|
||||
|
||||
const topFollowedQuery = query(
|
||||
collection(db, 'users'),
|
||||
users,
|
||||
orderBy('followerCountCached', 'desc'),
|
||||
limit(20)
|
||||
)
|
||||
|
||||
export function getUsers() {
|
||||
return getValues<User>(collection(db, 'users'))
|
||||
return getValues<User>(users)
|
||||
}
|
||||
|
||||
export async function getUserFeed(userId: string) {
|
||||
const feedDoc = doc(db, 'private-users', userId, 'cache', 'feed')
|
||||
const feedDoc = doc(privateUsers, userId, 'cache', 'feed')
|
||||
const userFeed = await getValue<{
|
||||
feed: feed
|
||||
}>(feedDoc)
|
||||
|
@ -222,7 +217,7 @@ export async function getUserFeed(userId: string) {
|
|||
}
|
||||
|
||||
export async function getCategoryFeeds(userId: string) {
|
||||
const cacheCollection = collection(db, 'private-users', userId, 'cache')
|
||||
const cacheCollection = collection(privateUsers, userId, 'cache')
|
||||
const feedData = await Promise.all(
|
||||
CATEGORY_LIST.map((category) =>
|
||||
getValue<{ feed: feed }>(doc(cacheCollection, `feed-${category}`))
|
||||
|
@ -233,7 +228,7 @@ export async function getCategoryFeeds(userId: string) {
|
|||
}
|
||||
|
||||
export async function follow(userId: string, followedUserId: string) {
|
||||
const followDoc = doc(db, 'users', userId, 'follows', followedUserId)
|
||||
const followDoc = doc(collection(users, userId, 'follows'), followedUserId)
|
||||
await setDoc(followDoc, {
|
||||
userId: followedUserId,
|
||||
timestamp: Date.now(),
|
||||
|
@ -241,7 +236,7 @@ export async function follow(userId: string, followedUserId: string) {
|
|||
}
|
||||
|
||||
export async function unfollow(userId: string, unfollowedUserId: string) {
|
||||
const followDoc = doc(db, 'users', userId, 'follows', unfollowedUserId)
|
||||
const followDoc = doc(collection(users, userId, 'follows'), unfollowedUserId)
|
||||
await deleteDoc(followDoc)
|
||||
}
|
||||
|
||||
|
@ -259,7 +254,7 @@ export function listenForFollows(
|
|||
userId: string,
|
||||
setFollowIds: (followIds: string[]) => void
|
||||
) {
|
||||
const follows = collection(db, 'users', userId, 'follows')
|
||||
const follows = collection(users, userId, 'follows')
|
||||
return listenForValues<{ userId: string }>(follows, (docs) =>
|
||||
setFollowIds(docs.map(({ userId }) => userId))
|
||||
)
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
import {
|
||||
collection,
|
||||
getDoc,
|
||||
getDocs,
|
||||
onSnapshot,
|
||||
Query,
|
||||
CollectionReference,
|
||||
DocumentReference,
|
||||
} from 'firebase/firestore'
|
||||
import { db } from './init'
|
||||
|
||||
export const coll = <T>(path: string, ...rest: string[]) => {
|
||||
return collection(db, path, ...rest) as CollectionReference<T>
|
||||
}
|
||||
|
||||
export const getValue = async <T>(doc: DocumentReference) => {
|
||||
const snap = await getDoc(doc)
|
||||
|
|
Loading…
Reference in New Issue
Block a user