Riki
Riki
CCConvex Community
Created by pez on 3/18/2025 in #support-community
Tips on sending batch notifications to a large group of users at once?
@pez I know that might not be the answer you are looking for, but most likely you could do that more easily OneSignal (an alternative to expo push notif), that has a RN SDK. Basically: 1. Every user in your app is registered thanks to the onesignal sdk 2. Every day you launch a cron on convex that calls the onesignal api 3. OneSignal handles for you push messaging ALL your users in one shot
16 replies
CCConvex Community
Created by Alvi on 3/16/2025 in #support-community
Convex image compression
@Alvi in case that helps, this is what I am doing so far: 1. Install sharp js package, and register it in your convex.json file
{
"node": {
"externalPackages": [
"sharp"
]
}
}
{
"node": {
"externalPackages": [
"sharp"
]
}
}
2. Add this file in your code:
'use node'

import { v } from 'convex/values'
import { internalAction } from '../_generated/server'
import sharp from 'sharp'
import { internal } from '../_generated/api'

export const optimizeImage = internalAction({
args: {
imageUrl: v.string(),
},
handler: async (ctx, args) => {
const req = await fetch(args.imageUrl)
const body = await req.arrayBuffer()

const imageSize = body.byteLength
let quality = 100
if (imageSize < 500_000) {
quality = 1
} else if (imageSize < 1_000_000) {
quality = 80
} else if (imageSize < 2_000_000) {
quality = 70
} else if (imageSize < 5_000_000) {
quality = 65
} else if (imageSize < 10_000_000) {
quality = 55
} else if (imageSize < 20_000_000) {
quality = 45
} else {
quality = 20
}
const imageBuffer = await sharp(body) // Load input image
.resize({
width: 1920,
height: 1920,
fit: 'inside', // Ensures the image fits within 1920x1920 while keeping aspect ratio
})
.webp({ quality: quality })
.toBuffer()

const blob = new Blob([imageBuffer], { type: 'image/webp' })
const storage = await ctx.storage.store(blob)

// Store your storageId in your db.
// To link that storageId to that url, you can either pass a unique id as function argument or return a generated id here.
},
})
'use node'

import { v } from 'convex/values'
import { internalAction } from '../_generated/server'
import sharp from 'sharp'
import { internal } from '../_generated/api'

export const optimizeImage = internalAction({
args: {
imageUrl: v.string(),
},
handler: async (ctx, args) => {
const req = await fetch(args.imageUrl)
const body = await req.arrayBuffer()

const imageSize = body.byteLength
let quality = 100
if (imageSize < 500_000) {
quality = 1
} else if (imageSize < 1_000_000) {
quality = 80
} else if (imageSize < 2_000_000) {
quality = 70
} else if (imageSize < 5_000_000) {
quality = 65
} else if (imageSize < 10_000_000) {
quality = 55
} else if (imageSize < 20_000_000) {
quality = 45
} else {
quality = 20
}
const imageBuffer = await sharp(body) // Load input image
.resize({
width: 1920,
height: 1920,
fit: 'inside', // Ensures the image fits within 1920x1920 while keeping aspect ratio
})
.webp({ quality: quality })
.toBuffer()

const blob = new Blob([imageBuffer], { type: 'image/webp' })
const storage = await ctx.storage.store(blob)

// Store your storageId in your db.
// To link that storageId to that url, you can either pass a unique id as function argument or return a generated id here.
},
})
8 replies
CCConvex Community
Created by Riki on 1/24/2025 in #support-community
React-Native / Jest / Convex-test setup issue
I tried a bunch of things like having convex-text added within the jest config field in my package.json as per recommended by the expo team: https://docs.expo.dev/develop/unit-testing/#additional-configuration-for-using-transformignorepatterns
"jest": {
"preset": "jest-expo",
"transformIgnorePatterns": [
"node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@sentry/react-native|native-base|react-native-svg|convex-test)"
]
},
"jest": {
"preset": "jest-expo",
"transformIgnorePatterns": [
"node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@sentry/react-native|native-base|react-native-svg|convex-test)"
]
},
But I still get a similar error.
8 replies
CCConvex Community
Created by Riki on 1/24/2025 in #support-community
React-Native / Jest / Convex-test setup issue
Hey @Tom it's strange but after investigation whenever I reinstall whatever version of convex-test, I get this error still
8 replies
CCConvex Community
Created by Riki on 1/24/2025 in #support-community
React-Native / Jest / Convex-test setup issue
I don’t know, but good idea to jnow. I will do a manual bisect with different versions and let you know
8 replies
CCConvex Community
Created by Riki on 1/24/2025 in #support-community
React-Native / Jest / Convex-test setup issue
8 replies
CCConvex Community
Created by Riki on 12/15/2024 in #support-community
.paginate combined with .withIndex is causing an error
Awesome, thanks @lee !!
30 replies
CCConvex Community
Created by Riki on 12/15/2024 in #support-community
.paginate combined with .withIndex is causing an error
I guess that's an unwanted side effect? I imagine they wanted here to bubble up the error in case it wasn't the InvalidCursor one given that should be the only acceptable error for paginated queries that the convex package can handle gracefully? But given if I'm not mistaken, the convex prod doesn't receive error messages, it is not able to find the "InvalidCursor" string and so falls back to bubbling up the error.
30 replies
CCConvex Community
Created by Riki on 12/15/2024 in #support-community
.paginate combined with .withIndex is causing an error
Oh lovely, thanks for the link
30 replies
CCConvex Community
Created by Riki on 12/15/2024 in #support-community
.paginate combined with .withIndex is causing an error
So you have in your codebase some paginated queries that rely on some internal query data and not "outside" query arguments?
30 replies
CCConvex Community
Created by Riki on 12/15/2024 in #support-community
.paginate combined with .withIndex is causing an error
No description
30 replies
CCConvex Community
Created by Riki on 12/15/2024 in #support-community
.paginate combined with .withIndex is causing an error
@erquhart I think you shared a wrong link? it seems this talk about convex website urls
30 replies
CCConvex Community
Created by Riki on 12/15/2024 in #support-community
.paginate combined with .withIndex is causing an error
@lee At least in React-Native an error thrown by the usePaginatedQuery hook needs an error boundary when connected to a prod convex environment (on dev we just have a warning, and it looks like it is handled by the hook itself which "restarts" a paginated query)
30 replies
CCConvex Community
Created by Riki on 12/15/2024 in #support-community
.paginate combined with .withIndex is causing an error
No description
30 replies
CCConvex Community
Created by Riki on 12/15/2024 in #support-community
.paginate combined with .withIndex is causing an error
export const getAllV2 = query({
args: {
paginationOpts: paginationOptsValidator,
},
handler: async (ctx, args) => {
const {authId} = await ensureAuthenticatedV2(ctx);

const me = await ctx.db
.query('user')
.withIndex('authId', q => q.eq('authId', authId))
.unique();
if (me == null) {
throw new ConvexError(ApiError.RESOURCE_NOT_FOUND);
}

const storiesByUsers = await ctx.db
.query('vHomeStory')
.withIndex('by_communityId', q => q.eq('communityId', me.communityId))
.paginate(args.paginationOpts);

const storiesWithImage = await asyncMapWitoutNull(
storiesByUsers.page,
async storiesByUser => {
const user = await ctx.db.get(storiesByUser.userId);

if (user == null) {
return;
}

const lastStories = await asyncMapWitoutNull(
storiesByUser.lastStories,
async lastStory => {
return {
creationTime: 12340123,
storyId: lastStory,
userId: storiesByUser.userId,
kind: 'IMAGE',
image: '',
duration: 100,
groupTitle: 'some_title',
groupId: 'some_id',
isLikedByMe: false,
};
},
);

return {
userId: storiesByUser.userId,
lastStoryTimestamp: storiesByUser.lastStoryTimestamp,
lastStories: lastStories,
imageUrl: user.imageUrls[0],
name: user.name,
authId: user.authId,
canMessage: true,
canLike: true,
canShareToSocial: true,
};
},
);

return {
...storiesByUsers,
page: storiesWithImage,
};
},
});
export const getAllV2 = query({
args: {
paginationOpts: paginationOptsValidator,
},
handler: async (ctx, args) => {
const {authId} = await ensureAuthenticatedV2(ctx);

const me = await ctx.db
.query('user')
.withIndex('authId', q => q.eq('authId', authId))
.unique();
if (me == null) {
throw new ConvexError(ApiError.RESOURCE_NOT_FOUND);
}

const storiesByUsers = await ctx.db
.query('vHomeStory')
.withIndex('by_communityId', q => q.eq('communityId', me.communityId))
.paginate(args.paginationOpts);

const storiesWithImage = await asyncMapWitoutNull(
storiesByUsers.page,
async storiesByUser => {
const user = await ctx.db.get(storiesByUser.userId);

if (user == null) {
return;
}

const lastStories = await asyncMapWitoutNull(
storiesByUser.lastStories,
async lastStory => {
return {
creationTime: 12340123,
storyId: lastStory,
userId: storiesByUser.userId,
kind: 'IMAGE',
image: '',
duration: 100,
groupTitle: 'some_title',
groupId: 'some_id',
isLikedByMe: false,
};
},
);

return {
userId: storiesByUser.userId,
lastStoryTimestamp: storiesByUser.lastStoryTimestamp,
lastStories: lastStories,
imageUrl: user.imageUrls[0],
name: user.name,
authId: user.authId,
canMessage: true,
canLike: true,
canShareToSocial: true,
};
},
);

return {
...storiesByUsers,
page: storiesWithImage,
};
},
});
30 replies
CCConvex Community
Created by Riki on 12/15/2024 in #support-community
.paginate combined with .withIndex is causing an error
@mikeysee Thanks for your message! I confirm I am using only one paginated query in the code. @lee yes indeed I am using usePaginatedQuery. Here is the code that I have simplified a bit but that's still triggering the error, sorry if it is still a bit long.
30 replies
CCConvex Community
Created by Riki on 12/15/2024 in #support-community
.paginate combined with .withIndex is causing an error
Oh yes definitely throwing an error, and so, caught by our error boundary screen
30 replies
CCConvex Community
Created by Riki on 12/11/2024 in #support-community
[Paginated Query] How to get the first elements in the "middle"
Ooooh lovely, thanks @jamalsoueidan and @lee !!
7 replies
CCConvex Community
Created by David Alonso on 11/2/2024 in #support-community
Mutation error: `Returned promise will never resolve` caused by triggers
Given I have another trigger that works and this trigger does nothing, I suspect this is something related to the mutation that happens within the 'users' table that is the issue (but it works well without the trigger)
54 replies
CCConvex Community
Created by David Alonso on 11/2/2024 in #support-community
Mutation error: `Returned promise will never resolve` caused by triggers
I have the same error. The "funny" part is that even if I edit the code of the trigger to do nothing (no query nor mutations), I get this error:
// testTrigger.ts
import {triggers} from './shared/triggers';

triggers.register('users', async (ctx, change) => {
// Do nothing
});
// testTrigger.ts
import {triggers} from './shared/triggers';

triggers.register('users', async (ctx, change) => {
// Do nothing
});
// function.ts
import {
mutation as rawMutation,
internalMutation as rawInternalMutation,
} from '../_generated/server';
import {customCtx, customMutation} from 'convex-helpers/server/customFunctions';
import {triggers} from './triggers';
import '../derivedUserFriends';
import '../testTrigger'; // THIS IMPORT CAUSES THE AFOREMENTIONED ERROR

export const mutation = customMutation(rawMutation, customCtx(triggers.wrapDB));
export const internalMutation = customMutation(
rawInternalMutation,
customCtx(triggers.wrapDB),
);
// function.ts
import {
mutation as rawMutation,
internalMutation as rawInternalMutation,
} from '../_generated/server';
import {customCtx, customMutation} from 'convex-helpers/server/customFunctions';
import {triggers} from './triggers';
import '../derivedUserFriends';
import '../testTrigger'; // THIS IMPORT CAUSES THE AFOREMENTIONED ERROR

export const mutation = customMutation(rawMutation, customCtx(triggers.wrapDB));
export const internalMutation = customMutation(
rawInternalMutation,
customCtx(triggers.wrapDB),
);
54 replies