makrdev
makrdev3w ago

R2 Store Method

There is a 'store' method in the documents to store files in actions but it's not available in the package.
27 Replies
Convex Bot
Convex Bot3w ago
Thanks for posting in <#1088161997662724167>. Reminder: If you have a Convex Pro account, use the Convex Dashboard to file support tickets. - Provide context: What are you trying to achieve, what is the end-user interaction, what are you seeing? (full error message, command output, etc.) - Use search.convex.dev to search Docs, Stack, and Discord all at once. - Additionally, you can post your questions in the Convex Community's <#1228095053885476985> channel to receive a response from AI. - Avoid tagging staff unless specifically instructed. Thank you!
makrdev
makrdevOP3w ago
No description
erquhart
erquhart3w ago
Are you sure you’re updated to latest? I’ll double check to make sure it’s published correctly in a bit.
makrdev
makrdevOP3w ago
Yeah, I'm on the latest version.
erquhart
erquhart3w ago
Alright, back at my machine in a couple hours, will fix
makrdev
makrdevOP3w ago
Thanks!
erquhart
erquhart3w ago
Can you run npm ls @convex-dev/r2 and make sure it's 0.4.0? I'm looking at the distributed code for that version and the store method is present both in types and runtime code. And if it is 0.4.0, can you share the code where you're using the store method
makrdev
makrdevOP6d ago
I had to delete and install it again. Now it works, so thanks for your support @erquhart Two more things: 1) It would be great if we can pass custom metadata. 2) It would be great if we can pass custom key. (Since we call this in server it's secure?)
erquhart
erquhart6d ago
store() is just a convience method for this:
const {key, url} = await r2.generateUploadUrl();
await fetch(url, {..my file});
await r2.syncMetadata(ctx, key);
const {key, url} = await r2.generateUploadUrl();
await fetch(url, {..my file});
await r2.syncMetadata(ctx, key);
And r2.generateUploadUrl() accepts an optional string key as it's only parameter, so you are able to customize the key. Should be supported on store too, though, and custom metadata makes sense, good asks 👍
makrdev
makrdevOP6d ago
Thanks for quick response. Glad you found it useful too. Keep up the good work!
erquhart
erquhart3d ago
@makrdev custom key can now be passed as 3rd param to r2.store: https://www.npmjs.com/package/@convex-dev/r2#storing-files-from-actions
makrdev
makrdevOP2d ago
Hey @erquhart, thanks! I got this error from store method: [TypeError: readableStream.getReader is not a function]
erquhart
erquhart2d ago
You're likely running into this dependency error with the aws sdk: https://github.com/aws/aws-sdk-js-v3/issues/6834 Not sure why I'm not getting it. I'll try downgrading and pinning per this recommendation: https://github.com/aws/aws-sdk-js-v3/issues/6834#issuecomment-2757283899 Released in 0.4.4, let me know if it works for you
makrdev
makrdevOP20h ago
It's still same with blob type. I wish we were able to pass other types than blob like Uint8Array<ArrayBufferLike> etc. Can we support all types supported by S3 client?
erquhart
erquhart20h ago
The example app in the repo uses a blob and works - can you help me repro?
makrdev
makrdevOP20h ago
// This doesn't work.
const example = internalAction({
args: {
key: v.string(),
string: v.string(),
},
handler: async (ctx, args) => {
try {
const file = new Blob([args.string], { type: "text/plain" });
await r2.store(ctx, file, args.key);

} catch (error) {
console.error(error);
throw new ConvexError("Failed to store.");
}
},
});
// This doesn't work.
const example = internalAction({
args: {
key: v.string(),
string: v.string(),
},
handler: async (ctx, args) => {
try {
const file = new Blob([args.string], { type: "text/plain" });
await r2.store(ctx, file, args.key);

} catch (error) {
console.error(error);
throw new ConvexError("Failed to store.");
}
},
});
erquhart
erquhart17h ago
const file = new Blob(["Hello, world!"], { type: "text/plain" });
await r2.store(ctx, file, "test-key");
const file = new Blob(["Hello, world!"], { type: "text/plain" });
await r2.store(ctx, file, "test-key");
No description
erquhart
erquhart17h ago
No description
erquhart
erquhart17h ago
@makrdev maybe try npm uninstalling and reinstalling the component?
makrdev
makrdevOP14h ago
Still no luck :/ I tested your example and it's not working too. Tested in node env and this is the error: Error at readableStreamHasher (convex:/user/_deps/node/H5VBUGX6.js:21456:15) at getAwsChunkedEncodingStream (convex:/user/_deps/node/H5VBUGX6.js:1293:41) at convex:/user/_deps/node/H5VBUGX6.js:9589:25 at processTicksAndRejections (node:internal/process/task_queues:95:5)
erquhart
erquhart14h ago
Ah so it's working in the Convex runtime but not in node, I've reproduced
makrdev
makrdevOP14h ago
Nope, it's not working in Convex runtime too. Just wanted to check if it works in Node but it's not.
erquhart
erquhart14h ago
Are you sure? I repro'd, and the bug is specifically because we're passing a blob and not a buffer in the Node env, not an issue in Convex runtime oh you had a different error earlier hmmm
makrdev
makrdevOP14h ago
Yeah, it was different error then.
erquhart
erquhart12h ago
Buffer/Uint8array support added in 0.5.0, should work in both environments Let me know if you're still getting those same errors. There's no "works on my machine" if you're running a Convex Cloud environment, so no clue why we're getting different results
makrdev
makrdevOP11h ago
const file = new TextEncoder().encode(args.filesString);
await r2.store(ctx, file, args.key);
const file = new TextEncoder().encode(args.filesString);
await r2.store(ctx, file, args.key);
Okay, this works now. Thanks!
erquhart
erquhart11h ago
good cuz I was out of solutions 😂

Did you find this page helpful?