timmm
timmm
Explore posts from servers
CCConvex Community
Created by timmm on 9/9/2024 in #support-community
Tanstack + Realtime not working
I'm using tanstack query and I'm not getting updates until I refresh the page Is there anything obvious I'm doing wrong? This pattern was adapted from the example on the tanstack website https://tanstack.com/router/v1/docs/framework/react/examples/start-convex-trellaux Here's the project table
projects: defineTable({
id: v.string(),
ownerUserId: v.id("users"),
name: v.string(),
})
.index("id", ["id"])
.index("ownerUserId", ["ownerUserId"]),
projects: defineTable({
id: v.string(),
ownerUserId: v.id("users"),
name: v.string(),
})
.index("id", ["id"])
.index("ownerUserId", ["ownerUserId"]),
This is my getProject code on the backend
async function ensureProjectExists(
ctx: QueryCtx,
id: string,
): Promise<Doc<"projects">> {
const project = await ctx.db
.query("projects")
.withIndex("id", (q) => q.eq("id", id))
.unique();

invariant(project, `missing project: ${id}`);
return project;
}

export const getProject = query({
args: {
projectId: v.string(),
},
handler: async (ctx, args) => {
const userId = await getAuthUserId(ctx);
if (userId === null) throw new Error("Not authenticated");
const project = withoutSystemFields(
await ensureProjectExists(ctx, args.projectId),
);
if (project.ownerUserId != userId) throw new Error("Not authorized");
return project;
},
});
async function ensureProjectExists(
ctx: QueryCtx,
id: string,
): Promise<Doc<"projects">> {
const project = await ctx.db
.query("projects")
.withIndex("id", (q) => q.eq("id", id))
.unique();

invariant(project, `missing project: ${id}`);
return project;
}

export const getProject = query({
args: {
projectId: v.string(),
},
handler: async (ctx, args) => {
const userId = await getAuthUserId(ctx);
if (userId === null) throw new Error("Not authenticated");
const project = withoutSystemFields(
await ensureProjectExists(ctx, args.projectId),
);
if (project.ownerUserId != userId) throw new Error("Not authorized");
return project;
},
});
This is my queries on the frontend
export const projectQueries = {
list: () => convexQuery(api.projects.getUsersProjects, {}),
getProject: ({ projectId }: { projectId: string }) =>
convexQuery(api.projects.getProject, { projectId }),
};

export function useCreateProjectMutation() {
const mutationFn = useConvexMutation(
api.projects.createProject,
).withOptimisticUpdate((localStore, args) => {
const { project } = args;

const { id: projectId } = project;
const projectQuery = localStore.getQuery(api.projects.getProject, {
projectId,
});
if (projectQuery) {
localStore.setQuery(
api.projects.getProject,
{ projectId },
{
id: project.id,
name: project.initialName,
ownerUserId: projectQuery.ownerUserId,
},
);
}
});

return useMutation({ mutationFn });
}
export const projectQueries = {
list: () => convexQuery(api.projects.getUsersProjects, {}),
getProject: ({ projectId }: { projectId: string }) =>
convexQuery(api.projects.getProject, { projectId }),
};

export function useCreateProjectMutation() {
const mutationFn = useConvexMutation(
api.projects.createProject,
).withOptimisticUpdate((localStore, args) => {
const { project } = args;

const { id: projectId } = project;
const projectQuery = localStore.getQuery(api.projects.getProject, {
projectId,
});
if (projectQuery) {
localStore.setQuery(
api.projects.getProject,
{ projectId },
{
id: project.id,
name: project.initialName,
ownerUserId: projectQuery.ownerUserId,
},
);
}
});

return useMutation({ mutationFn });
}
This is how i render it
export function ProjectChat({ projectId, chatId }: ProjectChatProps) {
const projectQuery = useSuspenseQuery(
convexQuery(api.projects.getProject, {
projectId,
}),
);

if (!projectQuery.data) {
return null;
}

return (
<div className="flex flex-col">
<div className="p-2">{projectQuery.data.name}</div>
<div className="flex">
<div className="w-[500px] flex-shrink-0">{projectQuery.data.name}</div>
<div className="flex-grow">test</div>
</div>
</div>
);
}
export function ProjectChat({ projectId, chatId }: ProjectChatProps) {
const projectQuery = useSuspenseQuery(
convexQuery(api.projects.getProject, {
projectId,
}),
);

if (!projectQuery.data) {
return null;
}

return (
<div className="flex flex-col">
<div className="p-2">{projectQuery.data.name}</div>
<div className="flex">
<div className="w-[500px] flex-shrink-0">{projectQuery.data.name}</div>
<div className="flex-grow">test</div>
</div>
</div>
);
}
9 replies
TTCTheo's Typesafe Cult
Created by timmm on 8/5/2024 in #questions
Invalid Signature in uploadthing
Hi - I'm getting an error "Invalid Signature" when I use upload thing with production settings. I can't find any reference to this error anywhere apart from in the code so I'm not sure where to start to resolve this The error in the console looks like this
⨯ UPLOADTHING 1:28:56 PM Invalid signature
⨯ UPLOADTHING 1:28:56 PM Invalid signature
I'm using remix I've setup my route handler API and as far as I can tell it looks fine The request object is being sent to the route handlers POST has an x-uploadthing-signature I've rotated the keys to double check and logging UPLOADTHING_SECRET shows the same secret that is in the upload thing api keys screen Everything works fine in dev mode This is my api/uploadthing route
import { ActionFunctionArgs, LoaderFunctionArgs } from "@remix-run/server-runtime";
import { uploadRouter } from "./uploadthing-config";
import { createRouteHandler } from "uploadthing/server";

const { GET, POST } = createRouteHandler({
router: uploadRouter,
config: {
uploadthingId: process.env.UPLOADTHING_APP_ID,
uploadthingSecret: process.env.UPLOADTHING_SECRET,
}
});

export async function loader({ request }: LoaderFunctionArgs) {
return GET(request);;
}

export async function action(action: ActionFunctionArgs) {
const response = await POST(action.request);
return response
}
import { ActionFunctionArgs, LoaderFunctionArgs } from "@remix-run/server-runtime";
import { uploadRouter } from "./uploadthing-config";
import { createRouteHandler } from "uploadthing/server";

const { GET, POST } = createRouteHandler({
router: uploadRouter,
config: {
uploadthingId: process.env.UPLOADTHING_APP_ID,
uploadthingSecret: process.env.UPLOADTHING_SECRET,
}
});

export async function loader({ request }: LoaderFunctionArgs) {
return GET(request);;
}

export async function action(action: ActionFunctionArgs) {
const response = await POST(action.request);
return response
}
What might be going on here?
3 replies