Search code examples
typescriptnext-auth

Unable to update user's profile picture


So the current default behaviour for next-auth is to just use the image the user had when the account was created. I want it to change so that if the user changes the image for that provider, this change should be reflected on the site.

The only mentioning of a similar problem I found was this: https://github.com/nextauthjs/next-auth/discussions/1414

Same approach should work in this case as well, but I am unable to access the fields I am interested in. The signature for the signIn is: signIn({ user, account, profile, email, credentials })

If I console.log(profile) I get the following:

{
  id: '218748538039828480',
  username: 'someUser',
  display_name: null,
  avatar: 'aa9f10fb12bb0f1ab225f78de5f06104',
  avatar_decoration: null,
  discriminator: '2043',
  public_flags: 256,
  flags: 256,
  banner: null,
  banner_color: '#6667ab',
  accent_color: 6711211,
  locale: 'en-GB',
  mfa_enabled: true,
  premium_type: 0,
  email: '[email protected]',
  verified: true,
  image_url: 'https://cdn.discordapp.com/avatars/218748538039828480/aa9f10fb12bb0f1ab225f78de5f06104.png'
}

Here we actually find what we want, the image_url field contains the newest image.

But TS and IntelliSense won't let me access it. The only options given for profile.<> is email, image, name and sub. All of which return a string or undefined, image in my attempts always return undefined. Despite image_url clearly being the image we wanted.


Solution

  • There's not much harm to be done if you know for sure that image_url will always exist:

    //@ts-ignore
    const imageUrl = profile.image_url;
    
    const imageUrl = (profile as unknown as { image_url: string }).image_url;
    
    const imageUrl: string = (profile as any).image_url;
    

    You could always be safe and use a guard clause:

    if (!("image_url" in profile)) {
        // no image_url
    }
    

    or heck, even make the image URL yourself:

    const imageUrl = `https://cdn.discordapp.com/avatars/${profile.id}/${profile.avatar}.png`;
    

    (this is how Discord avatar URLs look like; user id, followed by a hash)