rsnext/examples/with-supabase-auth-realtime-db
Kristoffer K 2acb53bd30
chore: update example names to match their folders (#16268)
**What's the problem this PR addresses?**

A decent amount of the examples don't have a `name` field in `package.json` that matches their folder name, meaning they either lack a name or the names are duplicated.

I was testing Yarn 2 workspaces using the entire examples directory and needed to get rid of the duplicates.

**How did you fix it?**

Updated the names to match the names of their folders
2020-09-05 21:23:51 +00:00
..
components examples: Add with-supabase-auth-realtime-db example. (#16016) 2020-08-13 05:03:09 +00:00
docs examples: Add with-supabase-auth-realtime-db example. (#16016) 2020-08-13 05:03:09 +00:00
lib examples: Add with-supabase-auth-realtime-db example. (#16016) 2020-08-13 05:03:09 +00:00
pages examples: Add with-supabase-auth-realtime-db example. (#16016) 2020-08-13 05:03:09 +00:00
styles examples: Add with-supabase-auth-realtime-db example. (#16016) 2020-08-13 05:03:09 +00:00
.env.local.example examples: Add with-supabase-auth-realtime-db example. (#16016) 2020-08-13 05:03:09 +00:00
.gitignore examples: Add with-supabase-auth-realtime-db example. (#16016) 2020-08-13 05:03:09 +00:00
jsconfig.json examples: Add with-supabase-auth-realtime-db example. (#16016) 2020-08-13 05:03:09 +00:00
package.json chore: update example names to match their folders (#16268) 2020-09-05 21:23:51 +00:00
README.md examples: Add with-supabase-auth-realtime-db example. (#16016) 2020-08-13 05:03:09 +00:00

Realtime chat example using Supabase

This is a full-stack Slack clone example using:

  • Frontend:
    • Next.js.
    • Supabase for user management and realtime data syncing.
  • Backend:
    • app.supabase.io: hosted Postgres database with restful API for usage with Supabase.js.

Demo animation gif

This example is a clone of the Slack Clone example in the supabase repo, feel free to check it out!

Deploy your own

Once you have access to the environment variables you'll need, deploy the example using Vercel:

Deploy with Vercel

How to use

Execute create-next-app with npm or Yarn to bootstrap the example:

npx create-next-app --example with-supabase-auth-realtime-db realtime-chat-app
# or
yarn create next-app --example with-supabase-auth-realtime-db realtime-chat-app

Configuration

Step 1. Create a new Supabase project

Sign up to Supabase - https://app.supabase.io and create a new project. Wait for your database to start.

Step 2. Run the "Slack Clone" Quickstart

Once your database has started, run the "Slack Clone" quickstart.

Slack Clone Quick Start

Step 3. Set up environment variables

In your Supabase project, go to Project Settings (the cog icon), open the API tab, and find your API URL and anon key, you'll need these in the next step.

image

Next, copy the .env.local.example file in this directory to .env.local (which will be ignored by Git):

cp .env.local.example .env.local

Then set each variable on .env.local:

  • NEXT_PUBLIC_SUPABASE_URL should be the API URL
  • NEXT_PUBLIC_SUPABASE_KEY should be the anon key

The anon key is your client-side API key. It allows "anonymous access" to your database, until the user has logged in. Once they have logged in, the keys will switch to the user's own login token. This enables row level security for your data. Read more about this below.

NOTE: The service_role key has full access to your data, bypassing any security policies. These keys have to be kept secret and are meant to be used in server environments and never on a client or browser.

Step 4. Run Next.js in development mode

npm install
npm run dev

# or

yarn install
yarn dev

Visit http://localhost:3000 and start chatting! Open a channel across two browser tabs to see everything getting updated in realtime 🥳. If it doesn't work, post on GitHub discussions.

Step 5. Deploy on Vercel

You can deploy this app to the cloud with Vercel (Documentation).

Deploy Your Local Project

To deploy your local project to Vercel, push it to GitHub/GitLab/Bitbucket and import to Vercel.

Important: When you import your project on Vercel, make sure to click on Environment Variables and set them to match your .env.local file.

Deploy from Our Template

Alternatively, you can deploy using our template by clicking on the Deploy button below.

Deploy with Vercel

Supabase details

Postgres Row level security

This project uses very high-level Authorization using Postgres' Role Level Security. When you start a Postgres database on Supabase, we populate it with an auth schema, and some helper functions. When a user logs in, they are issued a JWT with the role authenticated and thier UUID. We can use these details to provide fine-grained control over what each user can and cannot do.

This is a trimmed-down schema, with the policies:

-- USER PROFILES
CREATE TYPE public.user_status AS ENUM ('ONLINE', 'OFFLINE');
CREATE TABLE public.users (
  id uuid NOT NULL PRIMARY KEY, -- UUID from auth.users (Supabase)
  username text,
  status user_status DEFAULT 'OFFLINE'::public.user_status
);
ALTER TABLE public.users ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Allow logged-in read access" on public.users FOR SELECT USING ( auth.role() = 'authenticated' );
CREATE POLICY "Allow individual insert access" on public.users FOR INSERT WITH CHECK ( auth.uid() = id );
CREATE POLICY "Allow individual update access" on public.users FOR UPDATE USING ( auth.uid() = id );

-- CHANNELS
CREATE TABLE public.channels (
  id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
  inserted_at timestamp with time zone DEFAULT timezone('utc'::text, now()) NOT NULL,
  slug text NOT NULL UNIQUE
);
ALTER TABLE public.channels ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Allow logged-in full access" on public.channels FOR ALL USING ( auth.role() = 'authenticated' );

-- MESSAGES
CREATE TABLE public.messages (
  id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
  inserted_at timestamp with time zone DEFAULT timezone('utc'::text, now()) NOT NULL,
  message text,
  user_id uuid REFERENCES public.users NOT NULL,
  channel_id bigint REFERENCES public.channels NOT NULL
);
ALTER TABLE public.messages ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Allow logged-in read access" on public.messages USING ( auth.role() = 'authenticated' );
CREATE POLICY "Allow individual insert access" on public.messages FOR INSERT WITH CHECK ( auth.uid() = user_id );
CREATE POLICY "Allow individual update access" on public.messages FOR UPDATE USING ( auth.uid() = user_id );