KV store in NextJs App

I have a nextjs app that is a worker (following this guide). I also have a binding for KV ready (as seen in the pic). How can I use the kv binding to replace redis here?
import { FrameNotificationDetails } from "@farcaster/frame-sdk";
import { Redis } from "@upstash/redis";

const redis = new Redis({
url: process.env.KV_REST_API_URL,
token: process.env.KV_REST_API_TOKEN,
});

function getUserNotificationDetailsKey(fid: number): string {
return `user:${fid}`;
}

export async function getUserNotificationDetails(
fid: number
): Promise<FrameNotificationDetails | null> {
return await redis.get<FrameNotificationDetails>(
getUserNotificationDetailsKey(fid)
);
}

export async function setUserNotificationDetails(
fid: number,
notificationDetails: FrameNotificationDetails
): Promise<void> {
await redis.set(getUserNotificationDetailsKey(fid), notificationDetails);
}

export async function deleteUserNotificationDetails(
fid: number
): Promise<void> {
await redis.del(getUserNotificationDetailsKey(fid));
}
import { FrameNotificationDetails } from "@farcaster/frame-sdk";
import { Redis } from "@upstash/redis";

const redis = new Redis({
url: process.env.KV_REST_API_URL,
token: process.env.KV_REST_API_TOKEN,
});

function getUserNotificationDetailsKey(fid: number): string {
return `user:${fid}`;
}

export async function getUserNotificationDetails(
fid: number
): Promise<FrameNotificationDetails | null> {
return await redis.get<FrameNotificationDetails>(
getUserNotificationDetailsKey(fid)
);
}

export async function setUserNotificationDetails(
fid: number,
notificationDetails: FrameNotificationDetails
): Promise<void> {
await redis.set(getUserNotificationDetailsKey(fid), notificationDetails);
}

export async function deleteUserNotificationDetails(
fid: number
): Promise<void> {
await redis.del(getUserNotificationDetailsKey(fid));
}
Cloudflare Docs
Next.js · Cloudflare Workers docs
Create an Next.js application and deploy it to Cloudflare Workers with Workers Assets.
No description
8 Replies
thomasgauvin
thomasgauvin3d ago
Hey! Just wanted to make sure you were aware that Workers KV and upstash Redis are not the same thing and can't be used interchangeably as it seems you are doing
MazeMage
MazeMageOP3d ago
thank you for the answer, aren't they doing the same thing in this case (storing some small data and retrieving it when needed)? I was thinking they both kinda do the same. I tried even this approach:
import { FrameNotificationDetails } from "@farcaster/frame-sdk";
import { binding } from "cf-bindings-proxy";
import { KVNamespace } from "@cloudflare/workers-types";

const kv = binding<KVNamespace>("FARCASTER_NOTIFICATION_TOKENS_KV");

function getUserNotificationDetailsKey(fid: number): string {
return `user:${fid}`;
}

export async function getUserNotificationDetails(
fid: number
): Promise<FrameNotificationDetails | null> {
const value = await kv.get(getUserNotificationDetailsKey(fid));
return JSON.parse(value || "null");
}

export async function setUserNotificationDetails(
fid: number,
notificationDetails: FrameNotificationDetails
): Promise<void> {
console.log("kv in put: ", kv);
await kv.put(getUserNotificationDetailsKey(fid), JSON.stringify(notificationDetails));
}

export async function deleteUserNotificationDetails(
fid: number
): Promise<void> {
await kv.delete(getUserNotificationDetailsKey(fid));
}
import { FrameNotificationDetails } from "@farcaster/frame-sdk";
import { binding } from "cf-bindings-proxy";
import { KVNamespace } from "@cloudflare/workers-types";

const kv = binding<KVNamespace>("FARCASTER_NOTIFICATION_TOKENS_KV");

function getUserNotificationDetailsKey(fid: number): string {
return `user:${fid}`;
}

export async function getUserNotificationDetails(
fid: number
): Promise<FrameNotificationDetails | null> {
const value = await kv.get(getUserNotificationDetailsKey(fid));
return JSON.parse(value || "null");
}

export async function setUserNotificationDetails(
fid: number,
notificationDetails: FrameNotificationDetails
): Promise<void> {
console.log("kv in put: ", kv);
await kv.put(getUserNotificationDetailsKey(fid), JSON.stringify(notificationDetails));
}

export async function deleteUserNotificationDetails(
fid: number
): Promise<void> {
await kv.delete(getUserNotificationDetailsKey(fid));
}
but the kv const is undefined when I try to call it. Also I was wondering is the workers approach better than the pages for nextjs?
thomasgauvin
thomasgauvin2d ago
I would recommend that you go through our documentation and tutorials to understand how to use KV and Workers bindings. Start small with a simple application like this https://developers.cloudflare.com/workers/tutorials/build-a-jamstack-app/
Cloudflare Docs
Build a todo list Jamstack application · Cloudflare Workers docs
In this tutorial, you will build a todo list application using HTML, CSS, and JavaScript. The application data will be stored in Workers KV.
MazeMage
MazeMageOP2d ago
thank you, can I ask as well what is the best/easiest way to read a CF secret in a nextjs worker?
thomasgauvin
thomasgauvin2d ago
Your Next.js project, is it using next-on-pages https://github.com/cloudflare/next-on-pages or opennext https://opennext.js.org/cloudflare?
GitHub
GitHub - cloudflare/next-on-pages: CLI to build and develop Next.js...
CLI to build and develop Next.js apps for Cloudflare Pages - cloudflare/next-on-pages
Index - OpenNext
Open-source Next.js adapters
MazeMage
MazeMageOP2d ago
opennext, these docs are what i was looking for exactly, thank you
thomasgauvin
thomasgauvin2d ago
Excellent!
MazeMage
MazeMageOP2d ago
one more question, since I'm a nooby with nextjs. I have a component, where i want to use a secret. from the docs i see the env is accessable only in routers. is there any way to do it safely? the only way i can think of is to make api route, and call it inside the component, but this would make the route accessable to anybody, which defeats the purpose. is there a way to secure it?

Did you find this page helpful?