Home
> Creating a User Profile on Supabase Sign Up

</> About Firebase

</> Feature Wish List

📁 Authentication

</> User Document

📁 Cloud Firestore

</> Collections

</> Query Patterns

</> Data Converters

</> Timestamps

</> Reference Type

📁 Emulator Suite

</> Local Development

📁 Framework Setup

</> Qwik City

</> SvelteKit

</> NextJS

</> Nuxt

</> Analog

</> Remix

</> Angular SSR

</> Firebase Admin

👷 Under Construction

📧 Subscribe to our Newsletter for course and post updates!

Creating a User Profile on Supabase Sign Up

7 min read

Jonathan Gamble

jdgamble555 on Sunday, October 30, 2022 (last modified on Sunday, December 17, 2023)

One of the core things that people need to have is a public profile. The standard way is to create a profiles table. Your version of Supabase may do this automatically. It also depends on what login authentication methods you are using.

Users Private Schema#

  • When you create a user, your auth schema saves the data. Each individual login identity (google, apple, email...) along with the UUID is saved in the identities database.
  • Your user meta data from your authentication method is saved under users.raw_user_meta_data, and your provider methods are saved under users.raw_app_meta_data.

Methods#

Each method may have different options that are returned. The oAuth methods differ. Google will return your photo url as well as your name. Twitter may return your username. All of this is stored as JSON data in the raw-user_meta_data column.

Client#

You can access this data on the frontend by:

	supabase.auth.getUser();

or

	supabase.auth.getSession().then(session => session ? session.data.session?.user : null);

But you can also update that data. Your original methods will still be saved.

Update Data Methods#

Add a key#

Put the key(s) with in the data object.

	supabase.auth.updateUser({
  data: {
    avatar_url: 'https://...'
  }
});

The data object will save each individual key / value to the raw_user_meta_data JSON. It DOES NOT replace the entire JSON data, but only the key(s) you enter.

Remove a key#

Set the key(s) to null you want to remove.

	supabase.auth.updateUser({
  data: {
    avatar_url: null
  }
});

But how do you grab this data for your profiles table?

Method 1 - Trigger Function#

	CREATE OR REPLACE FUNCTION create_profile()
RETURNS TRIGGER AS $$
BEGIN
  INSERT INTO profile (id, display_name)
  VALUES (
    NEW.id,
    NEW.raw_user_meta_data ->> 'user_name'
  );
  RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

If you want the avatar_url, then do:

	  INSERT INTO profile (id, avatar_url)
  VALUES (
    NEW.id,
    NEW.raw_user_meta_data ->> 'avatar_url'
  );

This will make sure the data is inserted on creation.

But what about the front end methods?

Method 2 - onAuthStateChange#

You want to check that the user exists, then add it IFF it does not exist. I did not use await here since it is in a subscribing observable-like function.

Check User#

	const checkUser = (user: User): void => {

    // check for public profile record or create one
    supabase.from('profiles').select('*').eq('id', user.id)
        .then(({ data, error }) => {
            if (error) {
                console.error(error);
            }
            if (data.length === 0) {
                supabase.from('profiles').insert({
                    photo_url: user.user_metadata.avatar_url || null,
                    display_name: user.user_metadata.full_name || null
                }).then(({ error }) => {
                    if (error) {
                        console.error(error);
                    }
                });
            }
        });
}

Note: The full_name and avatar_url are usually only available on Google Authentication.

Look for changes#

You can use onAuthStateChange, or my simplified version:

	npm i j-supabase
	import { authUser } from 'j-supabase';
...
authUser(supabase).subscribe(user => {
  if (user) {
    checkUser(user);
    // ... then set user in store, hook, observable, or service
  }
});

For more on j-supabase

What content do I need?#

You don't want to copy all of the content. You only want to copy PUBLIC content. The user's email is already in the database and is not public, so you probably would not want to add that. A username, profile image, full name, etc. would be public information.

If your app allows a user to upload their own profile image, you would want to change it in TWO places. You want to change the public profile image, and their stored image using the updateUser() method above.

See my article on Firebase Authentication, and you will see you can create a user almost exactly the same way.

J


Related Posts

© 2024 Code.Build