entropyE
Convex Community2y ago
7 replies
entropy

Best way of querying documents when using Clerk

Hello! I'm currently working on a project that uses both Convex and Clerk together. I've been running into some issues with consistency within my backend when it comes to query documents by id and wanted to see if anyone had advice. The problem is that it's easy and convenient to query by a user's Clerk id, but I lose the type safety of the _id prop. It also leads to weird situations when creating relationships between tables. Should I just my me query function (returns user info protected by auth RLS) every time I want to query with a user id or is using the clerkId as the primary way of fetching a document a ok practice?

me function
export const me = authRLSQuery({
  handler: async ctx => {
    const user = await getUser(ctx, ctx.identity.subject)
    if (!user) {
      throw new ConvexError({ message: 'No user found for this identifier' })
    }
    return user
  }
})


utils
export async function getUser(ctx: QueryCtx | MutationCtx, clerkId: string) {
  const user = await ctx.db
    .query('users')
    .withIndex('by_clerkId', q => q.eq('clerkId', clerkId))
    .first()
  return user
}
export const authRLSQuery = customQuery(query, {
  args: {},
  input: async (ctx, args) => {
    const identity = await ctx.auth.getUserIdentity()
    if (!identity) {
      throw new ConvexError({
        code: 'UNAUTHORIZED',
        message: 'Sorry, you must be logged in to perform this action'
      })
    }

    const db = wrapDatabaseReader({ identity }, ctx.db, {
      users: {
        read: async (ctx, user) => ctx.identity.subject === user.clerkId
      }
    })
    return { ctx: { ...ctx, db, identity }, args }
  }
})
Was this page helpful?