From 7578cb24ad0f94b446dac062f91596063e54e5e8 Mon Sep 17 00:00:00 2001 From: Ian Philips Date: Fri, 22 Jul 2022 16:13:28 -0600 Subject: [PATCH] No nested queries :( --- common/contract.ts | 1 + firestore.rules | 2 +- functions/src/on-delete-group.ts | 13 +++++++++---- functions/src/scripts/convert-categories.ts | 10 +++++++--- .../src/scripts/link-contracts-to-groups.ts | 17 ++++++++++++----- web/hooks/use-group.ts | 6 +++--- web/lib/firebase/contracts.ts | 3 ++- web/lib/firebase/groups.ts | 2 ++ 8 files changed, 37 insertions(+), 17 deletions(-) diff --git a/common/contract.ts b/common/contract.ts index 9f19a91f..177af862 100644 --- a/common/contract.ts +++ b/common/contract.ts @@ -46,6 +46,7 @@ export type Contract = { collectedFees: Fees + groupSlugs?: string[] groupLinks?: GroupLink[] uniqueBettorIds?: string[] uniqueBettorCount?: number diff --git a/firestore.rules b/firestore.rules index 05ac8a6f..0f28ca80 100644 --- a/firestore.rules +++ b/firestore.rules @@ -74,7 +74,7 @@ service cloud.firestore { match /contracts/{contractId} { allow read; allow update: if request.resource.data.diff(resource.data).affectedKeys() - .hasOnly(['tags', 'lowercaseTags', 'groupLinks']); + .hasOnly(['tags', 'lowercaseTags', 'groupSlugs', 'groupLinks']); allow update: if request.resource.data.diff(resource.data).affectedKeys() .hasOnly(['description', 'closeTime', 'question']) && resource.data.creatorId == request.auth.uid; diff --git a/functions/src/on-delete-group.ts b/functions/src/on-delete-group.ts index 5c7a9336..e5531d7b 100644 --- a/functions/src/on-delete-group.ts +++ b/functions/src/on-delete-group.ts @@ -14,8 +14,9 @@ export const onDeleteGroup = functions.firestore // get all contracts with this group's slug const contracts = await firestore .collection('contracts') - .where('groupLinks.slug', '==', group.slug) + .where('groupSlugs', 'array-contains', group.slug) .get() + console.log("contracts with group's slug:", contracts) for (const doc of contracts.docs) { const contract = doc.data() as Contract @@ -24,8 +25,12 @@ export const onDeleteGroup = functions.firestore ) // remove the group from the contract - await firestore.collection('contracts').doc(contract.id).update({ - groupLinks: newGroupLinks, - }) + await firestore + .collection('contracts') + .doc(contract.id) + .update({ + groupSlugs: contract.groupSlugs?.filter((s) => s !== group.slug), + groupLinks: newGroupLinks ?? [], + }) } }) diff --git a/functions/src/scripts/convert-categories.ts b/functions/src/scripts/convert-categories.ts index ffcd7d6d..3436bcbc 100644 --- a/functions/src/scripts/convert-categories.ts +++ b/functions/src/scripts/convert-categories.ts @@ -84,9 +84,13 @@ const convertCategoriesToGroupsInternal = async (categories: string[]) => { name: newGroup.name, } as GroupLink, ] - await adminFirestore.collection('contracts').doc(market.id).update({ - groupLinks: newGroupLinks, - }) + await adminFirestore + .collection('contracts') + .doc(market.id) + .update({ + groupSlugs: uniq([...(market.groupSlugs ?? []), newGroup.slug]), + groupLinks: newGroupLinks, + }) } } } diff --git a/functions/src/scripts/link-contracts-to-groups.ts b/functions/src/scripts/link-contracts-to-groups.ts index b7ba513e..a4143deb 100644 --- a/functions/src/scripts/link-contracts-to-groups.ts +++ b/functions/src/scripts/link-contracts-to-groups.ts @@ -4,6 +4,7 @@ import { Contract } from 'common/contract' import { initAdmin } from 'functions/src/scripts/script-init' import * as admin from 'firebase-admin' import { filterDefined } from 'common/util/array' +import { uniq } from 'lodash' initAdmin() @@ -19,9 +20,11 @@ const addGroupIdToContracts = async () => { group.contractIds.includes(contract.id) ) for (const contract of groupContracts) { - const oldGroupLinks = contract.groupLinks ?? [] + const oldGroupLinks = contract.groupLinks?.filter( + (l) => l.slug === group.slug + ) const newGroupLinks = filterDefined([ - ...oldGroupLinks, + ...(oldGroupLinks ?? []), group.id ? { slug: group.slug, @@ -31,9 +34,13 @@ const addGroupIdToContracts = async () => { } : undefined, ]) - await adminFirestore.collection('contracts').doc(contract.id).update({ - groupLinks: newGroupLinks, - }) + await adminFirestore + .collection('contracts') + .doc(contract.id) + .update({ + groupSlugs: uniq([...(contract.groupSlugs ?? []), group.slug]), + groupLinks: newGroupLinks, + }) } } } diff --git a/web/hooks/use-group.ts b/web/hooks/use-group.ts index 20681954..84913962 100644 --- a/web/hooks/use-group.ts +++ b/web/hooks/use-group.ts @@ -109,11 +109,11 @@ export const useGroupsWithContract = (contract: Contract) => { const [groups, setGroups] = useState([]) useEffect(() => { - if (contract.groupLinks) - listGroups(uniq(contract.groupLinks.map((g) => g.slug))).then((groups) => + if (contract.groupSlugs) + listGroups(uniq(contract.groupSlugs)).then((groups) => setGroups(filterDefined(groups)) ) - }, [contract.groupLinks]) + }, [contract.groupSlugs]) return groups } diff --git a/web/lib/firebase/contracts.ts b/web/lib/firebase/contracts.ts index e16f6683..14594803 100644 --- a/web/lib/firebase/contracts.ts +++ b/web/lib/firebase/contracts.ts @@ -127,8 +127,9 @@ export async function listContracts(creatorId: string): Promise { export async function listContractsByGroupSlug( slug: string ): Promise { - const q = query(contracts, where('groupLinks.slug', '==', slug)) + const q = query(contracts, where('groupSlugs', 'array-contains', slug)) const snapshot = await getDocs(q) + console.log(snapshot.docs.map((doc) => doc.data())) return snapshot.docs.map((doc) => doc.data()) } diff --git a/web/lib/firebase/groups.ts b/web/lib/firebase/groups.ts index 36fb0e87..cd49e675 100644 --- a/web/lib/firebase/groups.ts +++ b/web/lib/firebase/groups.ts @@ -143,6 +143,7 @@ export async function addContractToGroup( ] await updateContract(contract.id, { + groupSlugs: uniq([...(contract.groupSlugs ?? []), group.slug]), groupLinks: newGroupLinks, }) return await updateGroup(group, { @@ -164,6 +165,7 @@ export async function removeContractFromGroup( const newGroupLinks = contract.groupLinks?.filter((link) => link.slug !== group.slug) ?? [] await updateContract(contract.id, { + groupSlugs: contract.groupSlugs?.filter((slug) => slug !== group.slug), groupLinks: newGroupLinks, }) const newContractIds = group.contractIds.filter((id) => id !== contract.id)