From ed0544212d133bb6af7447f9739beac6a2a72899 Mon Sep 17 00:00:00 2001 From: Marshall Polaris Date: Fri, 8 Jul 2022 15:00:03 -0700 Subject: [PATCH] Migrate changeUserInfo function to v2 (#626) --- functions/src/change-user-info.ts | 61 ++++++++++--------------------- functions/src/index.ts | 3 +- web/lib/firebase/api-call.ts | 4 ++ web/lib/firebase/fn-call.ts | 10 ----- web/pages/profile.tsx | 19 ++++------ 5 files changed, 32 insertions(+), 65 deletions(-) diff --git a/functions/src/change-user-info.ts b/functions/src/change-user-info.ts index 118d5c67..aa041856 100644 --- a/functions/src/change-user-info.ts +++ b/functions/src/change-user-info.ts @@ -1,5 +1,5 @@ -import * as functions from 'firebase-functions' import * as admin from 'firebase-admin' +import { z } from 'zod' import { getUser } from './utils' import { Contract } from '../../common/contract' @@ -11,37 +11,23 @@ import { } from '../../common/util/clean-username' import { removeUndefinedProps } from '../../common/util/object' import { Answer } from '../../common/answer' +import { APIError, newEndpoint, validate } from './api' -export const changeUserInfo = functions - .runWith({ minInstances: 1 }) - .https.onCall( - async ( - data: { - username?: string - name?: string - avatarUrl?: string - }, - context - ) => { - const userId = context?.auth?.uid - if (!userId) return { status: 'error', message: 'Not authorized' } +const bodySchema = z.object({ + username: z.string().optional(), + name: z.string().optional(), + avatarUrl: z.string().optional(), +}) - const user = await getUser(userId) - if (!user) return { status: 'error', message: 'User not found' } +export const changeuserinfo = newEndpoint({}, async (req, auth) => { + const { username, name, avatarUrl } = validate(bodySchema, req.body) - const { username, name, avatarUrl } = data + const user = await getUser(auth.uid) + if (!user) throw new APIError(400, 'User not found') - return await changeUser(user, { username, name, avatarUrl }) - .then(() => { - console.log('succesfully changed', user.username, 'to', data) - return { status: 'success' } - }) - .catch((e) => { - console.log('Error', e.message) - return { status: 'error', message: e.message } - }) - } - ) + await changeUser(user, { username, name, avatarUrl }) + return { message: 'Successfully changed user info.' } +}) export const changeUser = async ( user: User, @@ -55,14 +41,14 @@ export const changeUser = async ( if (update.username) { update.username = cleanUsername(update.username) if (!update.username) { - throw new Error('Invalid username') + throw new APIError(400, 'Invalid username') } const sameNameUser = await transaction.get( firestore.collection('users').where('username', '==', update.username) ) if (!sameNameUser.empty) { - throw new Error('Username already exists') + throw new APIError(400, 'Username already exists') } } @@ -104,17 +90,10 @@ export const changeUser = async ( ) const answerUpdate: Partial = removeUndefinedProps(update) - await transaction.update(userRef, userUpdate) - - await Promise.all( - commentSnap.docs.map((d) => transaction.update(d.ref, commentUpdate)) - ) - - await Promise.all( - answerSnap.docs.map((d) => transaction.update(d.ref, answerUpdate)) - ) - - await contracts.docs.map((d) => transaction.update(d.ref, contractUpdate)) + transaction.update(userRef, userUpdate) + commentSnap.docs.forEach((d) => transaction.update(d.ref, commentUpdate)) + answerSnap.docs.forEach((d) => transaction.update(d.ref, answerUpdate)) + contracts.docs.forEach((d) => transaction.update(d.ref, contractUpdate)) }) } diff --git a/functions/src/index.ts b/functions/src/index.ts index 8d1756f2..08639c7c 100644 --- a/functions/src/index.ts +++ b/functions/src/index.ts @@ -3,7 +3,6 @@ import * as admin from 'firebase-admin' admin.initializeApp() // v1 -// export * from './keep-awake' export * from './claim-manalink' export * from './transact' export * from './stripe' @@ -16,7 +15,6 @@ export * from './unsubscribe' export * from './update-metrics' export * from './update-stats' export * from './backup-db' -export * from './change-user-info' export * from './market-close-notifications' export * from './add-liquidity' export * from './on-create-answer' @@ -33,6 +31,7 @@ export * from './on-create-txn' // v2 export * from './health' +export * from './change-user-info' export * from './place-bet' export * from './sell-bet' export * from './sell-shares' diff --git a/web/lib/firebase/api-call.ts b/web/lib/firebase/api-call.ts index db41e592..341e92b0 100644 --- a/web/lib/firebase/api-call.ts +++ b/web/lib/firebase/api-call.ts @@ -50,6 +50,10 @@ export function getFunctionUrl(name: string) { } } +export function changeUserInfo(params: any) { + return call(getFunctionUrl('changeuserinfo'), 'POST', params) +} + export function createMarket(params: any) { return call(getFunctionUrl('createmarket'), 'POST', params) } diff --git a/web/lib/firebase/fn-call.ts b/web/lib/firebase/fn-call.ts index ce78ac3a..b9b771b5 100644 --- a/web/lib/firebase/fn-call.ts +++ b/web/lib/firebase/fn-call.ts @@ -42,16 +42,6 @@ export const createUser: () => Promise = () => { .catch(() => null) } -export const changeUserInfo = (data: { - username?: string - name?: string - avatarUrl?: string -}) => { - return cloudFunction('changeUserInfo')(data) - .then((r) => r.data as { status: string; message?: string }) - .catch((e) => ({ status: 'error', message: e.message })) -} - export const addLiquidity = (data: { amount: number; contractId: string }) => { return cloudFunction('addLiquidity')(data) .then((r) => r.data as { status: string }) diff --git a/web/pages/profile.tsx b/web/pages/profile.tsx index ac06eaf2..62177825 100644 --- a/web/pages/profile.tsx +++ b/web/pages/profile.tsx @@ -9,7 +9,7 @@ import { Title } from 'web/components/title' import { usePrivateUser, useUser } from 'web/hooks/use-user' import { formatMoney } from 'common/util/format' import { cleanDisplayName, cleanUsername } from 'common/util/clean-username' -import { changeUserInfo } from 'web/lib/firebase/fn-call' +import { changeUserInfo } from 'web/lib/firebase/api-call' import { uploadImage } from 'web/lib/firebase/storage' import { Col } from 'web/components/layout/col' import { Row } from 'web/components/layout/row' @@ -85,12 +85,9 @@ export default function ProfilePage() { if (newName) { setName(newName) - - await changeUserInfo({ name: newName }) - .catch(() => ({ status: 'error' })) - .then((r) => { - if (r.status === 'error') setName(user?.name || '') - }) + await changeUserInfo({ name: newName }).catch((_) => + setName(user?.name || '') + ) } else { setName(user?.name || '') } @@ -101,11 +98,9 @@ export default function ProfilePage() { if (newUsername) { setUsername(newUsername) - await changeUserInfo({ username: newUsername }) - .catch(() => ({ status: 'error' })) - .then((r) => { - if (r.status === 'error') setUsername(user?.username || '') - }) + await changeUserInfo({ username: newUsername }).catch((_) => + setUsername(user?.username || '') + ) } else { setUsername(user?.username || '') }