Storing data about a user
#
How the metadata updates workIn the SuperTokens core, we update the metadata using the following steps:
- Load old metadata from DB or use an empty object if we have nothing stored.
- Overwrite all root-level properties with the fields of the update object.
- Remove all root-level properties with a
null
value.
This way, you can update parts of the metadata object without loading and merging the whole thing yourself.
important
Only root-level properties are merged into the stored object. Nested objects and all lower-level properties will be replaced.
#
Example- The stored object has a theme set in preferences, emails enabled in notifications, and a single todo item, telling them to switch to text messages:
{ "preferences": { "theme": "dark" }, "notifications": { "email": true }, "todos": ["use-text-notifs"]}
- Now, we want to update this by changing the notification setting and removing the entire todo list:
{ "notifications": { "sms": true }, "todos": null}
- The result will be then:
{ "preferences": { "theme": "dark" }, "notifications": { "sms": true }}
#
How to use- NodeJS
- GoLang
- Python
- Express
- Hapi
- Fastify
- Koa
- Loopback
- AWS Lambda / Netlify
- Next.js
- NestJS
import express from "express";import { verifySession } from "supertokens-node/recipe/session/framework/express";import UserMetadata from "supertokens-node/recipe/usermetadata";
let app = express();
app.post("/updateinfo", verifySession(), async (req, res) => { const session = req.session; const userId = session.getUserId();
await UserMetadata.updateUserMetadata(userId, { newKey: "data" });
res.json({ message: "successfully updated user metadata" });});
import Hapi from "@hapi/hapi";import { verifySession } from "supertokens-node/recipe/session/framework/hapi";import { SessionRequest } from "supertokens-node/framework/hapi";import UserMetadata from "supertokens-node/recipe/usermetadata";
let server = Hapi.server({ port: 8000 });
server.route({ path: "/updateinfo", method: "post", options: { pre: [ { method: verifySession(), }, ], }, handler: async (req: SessionRequest, res) => { const session = req.session; const userId = session!.getUserId();
await UserMetadata.updateUserMetadata(userId, { newKey: "data" }); return res.response({ message: "successfully updated user metadata" }).code(200); },});
import Fastify from "fastify";import { verifySession } from "supertokens-node/recipe/session/framework/fastify";import UserMetadata from "supertokens-node/recipe/usermetadata";
let fastify = Fastify();
fastify.post( "/updateinfo", { preHandler: verifySession(), }, async (req, res) => { const session = req.session; const userId = session.getUserId();
await UserMetadata.updateUserMetadata(userId, { newKey: "data" }); res.send({ message: "successfully updated user metadata" }); },);
import { verifySession } from "supertokens-node/recipe/session/framework/awsLambda";import { SessionEvent } from "supertokens-node/framework/awsLambda";import UserMetadata from "supertokens-node/recipe/usermetadata";
async function updateinfo(awsEvent: SessionEvent) { const session = awsEvent.session; const userId = session!.getUserId();
await UserMetadata.updateUserMetadata(userId, { newKey: "data" });
return { body: JSON.stringify({ message: "successfully updated user metadata" }), statusCode: 200, };}
exports.handler = verifySession(updateinfo);
import KoaRouter from "koa-router";import { verifySession } from "supertokens-node/recipe/session/framework/koa";import { SessionContext } from "supertokens-node/framework/koa";import UserMetadata from "supertokens-node/recipe/usermetadata";
let router = new KoaRouter();
router.post("/updateinfo", verifySession(), async (ctx: SessionContext, next) => { const session = ctx.session; const userId = session!.getUserId();
await UserMetadata.updateUserMetadata(userId, { newKey: "data" }); ctx.body = { message: "successfully updated user metadata" };});
import { inject, intercept } from "@loopback/core";import { RestBindings, post, response } from "@loopback/rest";import { verifySession } from "supertokens-node/recipe/session/framework/loopback";import { SessionContext } from "supertokens-node/framework/loopback";import UserMetadata from "supertokens-node/recipe/usermetadata";
class UpdateInfo { constructor(@inject(RestBindings.Http.CONTEXT) private ctx: SessionContext) {} @post("/updateinfo") @intercept(verifySession()) @response(200) async handler() { const session = this.ctx.session; const userId = session!.getUserId();
await UserMetadata.updateUserMetadata(userId, { newKey: "data" }); return { message: "successfully updated user metadata" }; }}
import { superTokensNextWrapper } from "supertokens-node/nextjs";import { verifySession } from "supertokens-node/recipe/session/framework/express";import { SessionRequest } from "supertokens-node/framework/express";import UserMetadata from "supertokens-node/recipe/usermetadata";
export default async function updateInfo(req: any, res: any) { await superTokensNextWrapper( async (next) => { await verifySession()(req, res, next); }, req, res, ); const session = (req as SessionRequest).session; const userId = session!.getUserId();
await UserMetadata.updateUserMetadata(userId, { newKey: "data" }); res.json({ message: "successfully updated user metadata" });}
import { Controller, Post, UseGuards, Session } from "@nestjs/common";import { SessionContainer } from "supertokens-node/recipe/session";import UserMetadata from "supertokens-node/recipe/usermetadata";import { AuthGuard } from "./auth/auth.guard";
@Controller()export class ExampleController { // For more information about "AuthGuard" and the "Session" decorator please read our NestJS guide. @Post("example") @UseGuards(new AuthGuard()) async postExample(@Session() session: SessionContainer): Promise<{ message: string }> { const userId = session.getUserId();
await UserMetadata.updateUserMetadata(userId, { newKey: "data" }); return { message: "successfully updated user metadata" }; }}
import "github.com/supertokens/supertokens-golang/recipe/usermetadata"
func main() { userId := "..."
usermetadata.UpdateUserMetadata(userId, map[string]interface{}{ "newKey": "data", })}
- Asyncio
- Syncio
from supertokens_python.recipe.usermetadata.asyncio import update_user_metadata
async def some_func(): user_id = "..."
await update_user_metadata(user_id, { "newKey": "data" })
from supertokens_python.recipe.usermetadata.syncio import update_user_metadata
user_id = "..."
update_user_metadata(user_id, { "newKey": "data"})