kstulgys
kstulgys
CCConvex Community
Created by kstulgys on 9/27/2024 in #support-community
Is runMutation transactional?
await ctx.runMutation(internal.foo.create, {
foo: "xyz"
});
await ctx.runMutation(internal.bar.create, {
bar: "zyx"
});
await ctx.runMutation(internal.foo.create, {
foo: "xyz"
});
await ctx.runMutation(internal.bar.create, {
bar: "zyx"
});
will internal.bar.create be executed if internal.foo.create fails?
5 replies
CCConvex Community
Created by kstulgys on 9/17/2024 in #support-community
Whats the best practice/approach for saving and fetching convex images?
- Should I save storageId inside i.e product's table i.e thumbnail: v.id("_stareage") or should I have a separate table i.e productThumbnails? - If I have multiple images (previous question also applies) i.e images: v.array(v.id("_stareage")) when I delete I need to make sure I delete in both places (storage and in database) right? - Should I prefetch images in convex server side when I call i.e getProducts? i.e
return [...products, {...product, images: imageUrlsFromStorage} ]
return [...products, {...product, images: imageUrlsFromStorage} ]
Or should I fetch images client side where I have only storageId id?
7 replies
CCConvex Community
Created by kstulgys on 9/11/2024 in #support-community
Is this is valid Access-Control-Allow-Origin?
This is my http endpoint return:
return new Response(null, {
status: 200,
headers: new Headers({
"Access-Control-Allow-Origin": "*.xyz.com",
}),
});
return new Response(null, {
status: 200,
headers: new Headers({
"Access-Control-Allow-Origin": "*.xyz.com",
}),
});
Would this be valid? "Access-Control-Allow-Origin": "*.xyz.com" ? If not, is there a workaround? Sorry, too lazy to test myself.
3 replies
CCConvex Community
Created by kstulgys on 8/26/2024 in #support-community
how do I efficiently aggregate data?
How do I aggregate data? I.e I have orders, how do I calculate the total amount through entire period? I would assume querying all records and adding up the count wouldn't be the best option?
3 replies
CCConvex Community
Created by kstulgys on 8/24/2024 in #support-community
Is this is legit way to upload files? Haven't seen this in any example
With this approach you do not have to create http route. frontend:
function convertFileToBase64(file: File): Promise<string> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result as string);
reader.onerror = reject;
reader.readAsDataURL(file);
});
}

const upload = useAction(api.image.upload);

const handleUploadLogo = async (file: File | null) => {
if (!file) return;
const base64 = await convertFileToBase64(file);
await upload({ base64, table: "accounts", column: "logo" });
};
function convertFileToBase64(file: File): Promise<string> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result as string);
reader.onerror = reject;
reader.readAsDataURL(file);
});
}

const upload = useAction(api.image.upload);

const handleUploadLogo = async (file: File | null) => {
if (!file) return;
const base64 = await convertFileToBase64(file);
await upload({ base64, table: "accounts", column: "logo" });
};
8 replies
CCConvex Community
Created by kstulgys on 8/21/2024 in #support-community
How do I extend convex auth with my custom auth provider?
So idea is to pass 3 things from frontend
singIn("my-custom-provider", {address, message, signature})
singIn("my-custom-provider", {address, message, signature})
and this is where I'm stuck at:
export const { auth, signIn, signOut, store } = convexAuth({
providers: [
GitHub,
ConvexCredentials({
id: "my-custom-provider"
authorize: async (credentials, ctx) => {
const { address, message, signature } = credentials

const evmAddress = ethers.verifyMessage(message, signature);
const isVerified = evmAddress === address;

// ???
},
}),
],
});
export const { auth, signIn, signOut, store } = convexAuth({
providers: [
GitHub,
ConvexCredentials({
id: "my-custom-provider"
authorize: async (credentials, ctx) => {
const { address, message, signature } = credentials

const evmAddress = ethers.verifyMessage(message, signature);
const isVerified = evmAddress === address;

// ???
},
}),
],
});
How do I finish this implementation? Should I use ConvexCredentials or should I use something else?
3 replies
CCConvex Community
Created by kstulgys on 8/14/2024 in #support-community
Am I doing this ent query correctly?
export const get = authQuery({
args: {
orderId: v.id("orders"),
},
handler: async (ctx, args) => {
if (!ctx.user?.currentAccountId) return null;
const order = await ctx
.table("accounts")
.getX(ctx.user.currentAccountId)
.edgeX("orders")
.filter((q) => q.eq(q.field("_id"), args.orderId))
.firstX();
return order;
},
});
export const get = authQuery({
args: {
orderId: v.id("orders"),
},
handler: async (ctx, args) => {
if (!ctx.user?.currentAccountId) return null;
const order = await ctx
.table("accounts")
.getX(ctx.user.currentAccountId)
.edgeX("orders")
.filter((q) => q.eq(q.field("_id"), args.orderId))
.firstX();
return order;
},
});
I want to get order by id but that order must belong to the account that is ctx.user.currentAccountId
3 replies
CCConvex Community
Created by kstulgys on 8/12/2024 in #support-community
I want to deploy my website that uses convex development environment, how do I deal with SITE_URL?
I use convex auth, there are some variables that is required like SITE_URL. For this I use http://localhost:3000 when running locally, but I want to deploy my site as i.e xyz-test.com how can I manage different SITE_URL in this case?
25 replies
CCConvex Community
Created by kstulgys on 8/10/2024 in #support-community
Is convex capable to handle facebooks like traffic?
This question is merely experimental and just to check the intuition what convex is capable and what not.
8 replies
CCConvex Community
Created by kstulgys on 8/9/2024 in #support-community
I use convex auth with nextjs setup, but userId always null
export const authQuery = customQuery(
query,
customCtx(async (ctx) => {
const userId = await auth.getUserId(ctx);
if (!userId) throw new Error("Authentication required");
const user = (await ctx.db.get(userId))!;
return { userId, user };
})
);
export const authQuery = customQuery(
query,
customCtx(async (ctx) => {
const userId = await auth.getUserId(ctx);
if (!userId) throw new Error("Authentication required");
const user = (await ctx.db.get(userId))!;
return { userId, user };
})
);
13 replies
CCConvex Community
Created by kstulgys on 8/8/2024 in #support-community
What's the best way to manage long running functions in convex actions?
I have 3 async functions that depend one on each other so I can not do Promise.all I'm running these in internal action ("use node") each function can take ~5 seconds so total action execution time could take ~15 seconds Is this is healthy for convex? is there a better way todo this?
10 replies
CCConvex Community
Created by kstulgys on 8/5/2024 in #support-community
Why sometime ents one-to-one with optional: true work, sometimes not?
so my schema is this:
wallets: defineEnt({
privateKey: v.string(),
})
.edge("balance", { optional: true })
.edge("user")
.edge("store"),

balances: defineEnt({
balance: v.any() as BalanceMap,
})
.edge("wallet")
.edge("store")
.edge("user"),
wallets: defineEnt({
privateKey: v.string(),
})
.edge("balance", { optional: true })
.edge("user")
.edge("store"),

balances: defineEnt({
balance: v.any() as BalanceMap,
})
.edge("wallet")
.edge("store")
.edge("user"),
I first create wallet then I create balance
// create wallet
const walletId = await ctx.db.insert("wallets", {
privateKey: wallet.privateKey,
userId: ctx.userId,
storeId,
});

// create balance
const balanceId = await ctx.db.insert("balances", {
walletId,
balance: initialBalance,
userId: ctx.userId,
storeId,
});

// connect balance to the wallet
await ctx.db.patch(walletId, { balanceId });

// ❌ this is where ts and console is not happy. no balanceId field on wallet table, but walletId field on balance seem to be fine
// create wallet
const walletId = await ctx.db.insert("wallets", {
privateKey: wallet.privateKey,
userId: ctx.userId,
storeId,
});

// create balance
const balanceId = await ctx.db.insert("balances", {
walletId,
balance: initialBalance,
userId: ctx.userId,
storeId,
});

// connect balance to the wallet
await ctx.db.patch(walletId, { balanceId });

// ❌ this is where ts and console is not happy. no balanceId field on wallet table, but walletId field on balance seem to be fine
In other cases I also use this approach with optional: true and it seem to work fine
20 replies
CCConvex Community
Created by kstulgys on 8/5/2024 in #support-community
Is there a way to run some code just after user is created?
If yes then when and where? Is there a way to "listen" when new user or some new entry in table is created?
24 replies
CCConvex Community
Created by kstulgys on 8/4/2024 in #support-community
can I use convex auth with hono?
There is no such example convex auth and hono.
10 replies
CCConvex Community
Created by kstulgys on 8/1/2024 in #support-community
Convex auth does not work with defineEntSchema
No description
9 replies
CCConvex Community
Created by kstulgys on 8/1/2024 in #support-community
How do I define a more complex object with convex values?
is there a way to define object like:
type Product = { ... }

Record<string,Product>

// string is product id (_id)
type Product = { ... }

Record<string,Product>

// string is product id (_id)
I know this is incorrect:
v.object({
[v.id("products")]: v.object({...})
})
v.object({
[v.id("products")]: v.object({...})
})
4 replies
CCConvex Community
Created by kstulgys on 7/30/2024 in #support-community
Can I use convex file storage to upload a javascript file?
I want to upload/update my javascript file then use it like: <script src="https://my-convex-storage/my-script.js"/> is that possible? is that normal lol?
13 replies
CCConvex Community
Created by kstulgys on 4/6/2024 in #support-community
Can I make table relation field optional? Example 👇
users: defineEnt({})
.field("email", v.string(), { unique: true })
.edges("apiKeys", { ref: true }),
.edges("downloads", { ref: true })

apiKeys: defineEnt({})
.field("hashedApiKey", v.string(), { unique: true })
.edges("downloads", { ref: true })
.edge("user"),

downloads: defineEnt({})
.edge("user")
.edge("apiKey"),
users: defineEnt({})
.field("email", v.string(), { unique: true })
.edges("apiKeys", { ref: true }),
.edges("downloads", { ref: true })

apiKeys: defineEnt({})
.field("hashedApiKey", v.string(), { unique: true })
.edges("downloads", { ref: true })
.edge("user"),

downloads: defineEnt({})
.edge("user")
.edge("apiKey"),
I want todo this and this is not working, convex complains:
downloads: defineEnt({})
.edge("user", { optional: true })
.edge("apiKey", { optional: true }),
downloads: defineEnt({})
.edge("user", { optional: true })
.edge("apiKey", { optional: true }),
2 replies
CCConvex Community
Created by kstulgys on 3/18/2024 in #support-community
Is there a way to delete or update item without using db.delete and db.patch?
I want to delete or update item but lets say I can not use _id
8 replies
CCConvex Community
Created by kstulgys on 3/18/2024 in #support-community
how do I create one-to-one edge relation?
tags: defineEnt({
name: v.string(),
}).edge("post"),

posts: defineEnt({
title: v.string(),
body: v.string(),
}).edge("tag"),
tags: defineEnt({
name: v.string(),
}).edge("post"),

posts: defineEnt({
title: v.string(),
body: v.string(),
}).edge("tag"),
One post has one tag and one tag has one post. How do I create these records at the same time? Because one needs to exist before the other.
7 replies