additionalFields not showing in user or session

I have followed every doc imaginable to get some custom fields passed from my NestJS backend to my expo app client, and nothing seems to work. I have the fields set in my auth config on server, and am using the inferAdditionalFields plugin with my expo client, and no luck.
1 Reply
Rich Prins
Rich PrinsOP2mo ago
import { betterAuth } from 'better-auth';
import { prismaAdapter } from 'better-auth/adapters/prisma';
import { PrismaClient } from '@prisma/client';
import { admin } from 'better-auth/plugins';
import { expo } from '@better-auth/expo';

const prisma = new PrismaClient();

export const auth = betterAuth({
database: prismaAdapter(prisma, {
provider: 'postgresql',
}),
user: {
additionalFields: {
completedOnboarding: {
type: 'boolean',
required: false,
defaultValue: false,
input: false,
returned: true,
},
onboardingStep: {
type: 'string',
required: false,
defaultValue: '',
input: false,
returned: true,
},
role: {
type: 'string',
required: false,
defaultValue: 'user',
input: false,
returned: true,
},
},
},
emailAndPassword: {
enabled: true,
requireEmailVerification: true,
sendResetPassword: async () => {},
},
emailVerification: {
sendOnSignUp: true,
expiresIn: 1000 * 60 * 60 * 24,
autoSignInAfterVerification: true,
sendVerificationEmail: async ({ user, url, token }, request) => {},
},
plugins: [
expo(),
admin({
defaultBanReason: 'Misconduct/Inappropriate Behavior',
adminRoles: ['admin', 'superadmin'],
}),
],
});
import { betterAuth } from 'better-auth';
import { prismaAdapter } from 'better-auth/adapters/prisma';
import { PrismaClient } from '@prisma/client';
import { admin } from 'better-auth/plugins';
import { expo } from '@better-auth/expo';

const prisma = new PrismaClient();

export const auth = betterAuth({
database: prismaAdapter(prisma, {
provider: 'postgresql',
}),
user: {
additionalFields: {
completedOnboarding: {
type: 'boolean',
required: false,
defaultValue: false,
input: false,
returned: true,
},
onboardingStep: {
type: 'string',
required: false,
defaultValue: '',
input: false,
returned: true,
},
role: {
type: 'string',
required: false,
defaultValue: 'user',
input: false,
returned: true,
},
},
},
emailAndPassword: {
enabled: true,
requireEmailVerification: true,
sendResetPassword: async () => {},
},
emailVerification: {
sendOnSignUp: true,
expiresIn: 1000 * 60 * 60 * 24,
autoSignInAfterVerification: true,
sendVerificationEmail: async ({ user, url, token }, request) => {},
},
plugins: [
expo(),
admin({
defaultBanReason: 'Misconduct/Inappropriate Behavior',
adminRoles: ['admin', 'superadmin'],
}),
],
});
import * as SecureStore from "expo-secure-store"
import { expoClient } from "@better-auth/expo/client"
import { inferAdditionalFields } from "better-auth/client/plugins"
import { createAuthClient } from "better-auth/react"

import Config from "@/config"

export const authClient = createAuthClient({
baseURL: Config.API_URL, // Base URL of your Better Auth backend.
plugins: [
expoClient({
scheme: "xxxxxxxxxxxxxxxx",
storagePrefix: "xxxxxxxxxxxxxxx",
storage: SecureStore,
}),
inferAdditionalFields({
user: {
completedOnboarding: {
type: "boolean",
required: false,
},
onboardingStep: {
type: "string",
required: false,
},
role: {
type: "string",
required: false,
},
},
}),
],
})
import * as SecureStore from "expo-secure-store"
import { expoClient } from "@better-auth/expo/client"
import { inferAdditionalFields } from "better-auth/client/plugins"
import { createAuthClient } from "better-auth/react"

import Config from "@/config"

export const authClient = createAuthClient({
baseURL: Config.API_URL, // Base URL of your Better Auth backend.
plugins: [
expoClient({
scheme: "xxxxxxxxxxxxxxxx",
storagePrefix: "xxxxxxxxxxxxxxx",
storage: SecureStore,
}),
inferAdditionalFields({
user: {
completedOnboarding: {
type: "boolean",
required: false,
},
onboardingStep: {
type: "string",
required: false,
},
role: {
type: "string",
required: false,
},
},
}),
],
})
LOG Full session object: {
"session": {
"expiresAt": "2025-11-11T22:53:43.961Z",
"token": "xxxxxxxxxxxxxxxxx",
"createdAt": "2025-11-04T22:53:43.962Z",
"updatedAt": "2025-11-04T22:53:43.962Z",
"ipAddress": "",
"userAgent": "xxxxxxxxxxxxxxx/1 CFNetwork/3826.400.120 Darwin/24.2.0",
"userId": "xxxxxxxxxxxxxxxxx",
"impersonatedBy": null,
"id": "xxxxxxxxxxxxxxxx"
},
"user": {
"name": "Default User",
"email": "xxxxxxxxxxxxx@gmail.com",
"emailVerified": true,
"image": null,
"createdAt": "2025-09-30T22:29:21.447Z",
"updatedAt": "2025-09-30T22:29:21.447Z",
"role": "user",
"banned": false,
"banReason": null,
"banExpires": null,
"id": "xxxxxxxxxxxxxxxx"
}
}
LOG User object: {
"name": "Default User",
"email": "xxxxxxxxxxxxxxx@gmail.com",
"emailVerified": true,
"image": null,
"createdAt": "2025-09-30T22:29:21.447Z",
"updatedAt": "2025-09-30T22:29:21.447Z",
"role": "user",
"banned": false,
"banReason": null,
"banExpires": null,
"id": "xxxxxxxxxxxxxxxx"
}
LOG Full session object: {
"session": {
"expiresAt": "2025-11-11T22:53:43.961Z",
"token": "xxxxxxxxxxxxxxxxx",
"createdAt": "2025-11-04T22:53:43.962Z",
"updatedAt": "2025-11-04T22:53:43.962Z",
"ipAddress": "",
"userAgent": "xxxxxxxxxxxxxxx/1 CFNetwork/3826.400.120 Darwin/24.2.0",
"userId": "xxxxxxxxxxxxxxxxx",
"impersonatedBy": null,
"id": "xxxxxxxxxxxxxxxx"
},
"user": {
"name": "Default User",
"email": "xxxxxxxxxxxxx@gmail.com",
"emailVerified": true,
"image": null,
"createdAt": "2025-09-30T22:29:21.447Z",
"updatedAt": "2025-09-30T22:29:21.447Z",
"role": "user",
"banned": false,
"banReason": null,
"banExpires": null,
"id": "xxxxxxxxxxxxxxxx"
}
}
LOG User object: {
"name": "Default User",
"email": "xxxxxxxxxxxxxxx@gmail.com",
"emailVerified": true,
"image": null,
"createdAt": "2025-09-30T22:29:21.447Z",
"updatedAt": "2025-09-30T22:29:21.447Z",
"role": "user",
"banned": false,
"banReason": null,
"banExpires": null,
"id": "xxxxxxxxxxxxxxxx"
}
model User {
id String @id @default(uuid())
name String
email String
emailVerified Boolean
image String?
createdAt DateTime
updatedAt DateTime
role String?
banned Boolean?
banReason String?
banExpires DateTime?
username String?
displayUsername String?

completedOnboarding Boolean @default(false)
onboardingStep String?

sessions Session[]
accounts Account[]
checkIns CheckIn[]
dailyGoals DailyGoal[]

@@map("user")
}
model User {
id String @id @default(uuid())
name String
email String
emailVerified Boolean
image String?
createdAt DateTime
updatedAt DateTime
role String?
banned Boolean?
banReason String?
banExpires DateTime?
username String?
displayUsername String?

completedOnboarding Boolean @default(false)
onboardingStep String?

sessions Session[]
accounts Account[]
checkIns CheckIn[]
dailyGoals DailyGoal[]

@@map("user")
}

Did you find this page helpful?