#Convex Auth setting user profile data on every login

5 messages · Page 1 of 1 (latest)

worthy leaf
#

I'm using Convex Auth with Google as a provider. Whenever a user logs in with Google, it sets their name and image to that of their Google account, even if they have a different one set on the site already. This is expected on signup, but not on signin, as some users will have public display names that get replaced by their real name, which isn't ideal. Is there any solution I can take to disable or override this behavior?

ocean belfryBOT
#

Hi @worthy leaf. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

Yes. You have two supported options to stop OAuth logins from overwriting your existing user profile fields:

  1. Customize the OAuth provider’s profile mapping so you only set fields at signup (or only when missing)
  • Implement the provider’s profile() and return only the fields you want to persist. You can add custom fields too. [Retrieving info]
  • To ensure you don’t overwrite user-edited fields on subsequent sign-ins, use the createOrUpdateUser callback (below) or only return fields you’re comfortable overwriting.

Example (Google), showing how to shape the OAuth profile:

import Google from "@auth/core/providers/google";
import { convexAuth } from "@convex-dev/auth/server";

export const { auth, signIn, signOut, store, isAuthenticated } = convexAuth({
  providers: [
    Google({
      profile(googleProfile) {
        return {
          id: googleProfile.sub,
          // name/email/image provided, but whether they’re stored/updated is controlled below
          name: googleProfile.name,
          email: googleProfile.email,
          image: googleProfile.picture,
        };
      },
    }),
  ],
});

[Retrieving info]

#
  1. Fully control when profile fields are created vs. updated via callbacks.createOrUpdateUser
  • This callback is invoked during sign-in before account creation/token generation, and if provided, Convex Auth won’t auto-create or auto-update the user—your code does. You can detect if the user exists and only set name/image on first creation, leaving them unchanged on later logins. [CreateOrUpdateUser; Account linking]

Sketch:

import Google from "@auth/core/providers/google";
import { convexAuth } from "@convex-dev/auth/server";

export const { auth, signIn, signOut, store, isAuthenticated } = convexAuth({
  providers: [Google()],
  callbacks: {
    async createOrUpdateUser(ctx, args) {
      // args.profile has OAuth profile
      const { profile } = args;

      if (args.existingUserId) {
        // User exists: do NOT overwrite user-edited fields like name/image.
        return args.existingUserId;
      }

      // New user: set initial fields once.
      return await ctx.db.insert("users", {
        email: profile.email,
        name: profile.name,      // only set at signup
        image: profile.image,    // only set at signup
        // any other defaults...
      });
    },
  },
});
#

Notes:

  • If you don’t need full control, an alternative is callbacks.afterUserCreatedOrUpdated, but it only runs when createOrUpdateUser isn’t provided and doesn’t replace the built-in create/update logic; for precise control over overwrites, use createOrUpdateUser. [After created/updated]
  • If you add custom fields from the OAuth profile, remember to add them to your users schema. [Retrieving info]

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: