-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
53 changed files
with
290 additions
and
18 deletions.
There are no files selected for viewing
18 changes: 0 additions & 18 deletions
18
examples/auth/user_managment/phoenix_live_view_user_management/README.md
This file was deleted.
Oops, something went wrong.
File renamed without changes.
File renamed without changes.
File renamed without changes.
75 changes: 75 additions & 0 deletions
75
examples/user_managment/phoenix_live_view_user_management/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
# Supabase Phoenix LiveView User Management | ||
|
||
This repo is a quick sample of how you can get started building apps using [Phoenix LiveView](https://phoenixframework.org) and Supabase. You can find a step by step guide of how to build out this app in the [Quickstart: Phoenix LiveView guide](./guides/quickstart.md). | ||
|
||
This repo will demonstrate how to: | ||
|
||
- sign users in with Supabase Auth using [magic link](https://supabase.io/docs/reference/dart/auth-signin#sign-in-with-magic-link) | ||
- store and retrieve data with [Supabase database](https://supabase.io/docs/guides/database) | ||
- store image files in [Supabase storage](https://supabase.io/docs/guides/storage) | ||
|
||
## Getting Started | ||
|
||
Before running this app, you need to create a Supabase project and copy [your credentials](./guides/quickstart.md#get-the-api-keys) to `.env` or you can safely use [supabase-cli](https://supabase.com/docs/guides/cli/getting-started) and use the already defined `.env.dev`. | ||
|
||
Run the following command to launch it on `localhost:4000` | ||
|
||
```bash | ||
mix dev | ||
``` | ||
|
||
> Note that this command `mix dev` is a custom alias defind on `mix.exs`. | ||
## Database Schema | ||
|
||
```sql | ||
-- Create a table for public "profiles" | ||
create table profiles ( | ||
id uuid references auth.users not null, | ||
updated_at timestamp with time zone, | ||
username text unique, | ||
avatar_url text, | ||
website text, | ||
|
||
primary key (id), | ||
unique(username), | ||
constraint username_length check (char_length(username) >= 3) | ||
); | ||
|
||
alter table profiles enable row level security; | ||
|
||
create policy "Public profiles are viewable by everyone." | ||
on profiles for select | ||
using ( true ); | ||
|
||
create policy "Users can insert their own profile." | ||
on profiles for insert | ||
with check ( (select auth.uid()) = id ); | ||
|
||
create policy "Users can update own profile." | ||
on profiles for update | ||
using ( (select auth.uid()) = id ); | ||
|
||
-- Set up Realtime! | ||
begin; | ||
drop publication if exists supabase_realtime; | ||
create publication supabase_realtime; | ||
commit; | ||
alter publication supabase_realtime add table profiles; | ||
|
||
-- Set up Storage! | ||
insert into storage.buckets (id, name) | ||
values ('avatars', 'avatars'); | ||
|
||
create policy "Avatar images are publicly accessible." | ||
on storage.objects for select | ||
using ( bucket_id = 'avatars' ); | ||
|
||
create policy "Anyone can upload an avatar." | ||
on storage.objects for insert | ||
with check ( bucket_id = 'avatars' ); | ||
``` | ||
|
||
> [!INFO] | ||
> You can find the SQL schema in the [migrations](./priv/repo/migrations) folder. | ||
> Generally you would prefer to use direct connection between your app (with ecto) and the Supabase postgres intances instead of using PostgREST |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
128 changes: 128 additions & 0 deletions
128
examples/user_managment/phoenix_live_view_user_management/guides/quickstart.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
# Build a User Management App with Phoenix LiveView | ||
|
||
Learn how to use Supabase in your Phoenix LiveView App. | ||
|
||
This tutorial demonstrates how to build a basic user management app. The app authenticates and identifies the user, stores their profile information in the database, and allows the user to log in, update their profile details, and upload a profile photo. The app uses: | ||
|
||
- [Supabase Database](https://supabase.com/docs/guides/database) - a Postgres database for storing your user data and [Row Level Security](https://supabase.com/docs/guides/auth#row-level-security) so data is protected and users can only access their own information. | ||
- [Supabase Auth](https://supabase.com/docs/guides/auth) - allow users to sign up and log in. | ||
- [Supabase Storage](https://supabase.com/docs/guides/storage) - users can upload a profile photo. | ||
|
||
![Supabase User Management example](https://supabase.com/docs/img/user-management-demo.png) | ||
|
||
> [!INFO] | ||
> If you get stuck while working through this guide, refer to the [full example on GitHub](https://github.com/zoedsoupe/supabase-ex/tree/main/examples/user_management/phoenix_live_view_user_management). | ||
## Project Setup | ||
|
||
Before we start building we're going to set up our Database and API. This is as simple as starting a new Project in Supabase and then creating a "schema" inside the database. | ||
|
||
### Create a Project | ||
|
||
1. [Create a new project](https://supabase.com/dashboard) in the Supabase Dashboard. | ||
2. Enter your project details. | ||
3. Wait for the new database to launch. | ||
|
||
### Set up the database schema | ||
|
||
I'll be doing that using the [Ecto migrations](https://hexdocs.pm/ecto_sql), but you can also do that manually in the Supabase Dashboard. | ||
|
||
### Get the API Keys | ||
|
||
Now that you've created some database tables, you are ready to insert data using the auto-generated API. We just need to get the Project URL and `anon` key from the API settings. | ||
|
||
1. Go to the [API Settings](https://supabase.com/dashboard/project/_/settings/api) page in the Dashboard. | ||
2. Find your Project `URL`, `anon`, and `service_role` keys on this page. | ||
|
||
## Building the app | ||
|
||
Let's start building the Phoenix LiveView app from scratch. | ||
|
||
### Initialize a Phoenix LiveView app | ||
|
||
We can use [`mix phx.new`](https://hexdocs.pm/phoenix/Mix.Tasks.Phx.New.html) to create an app called `arcane`: | ||
|
||
> Before issuing this command, ensure you have [elixir](https://elixir-lang.org) installed | ||
> Also ensure that you have the [phoenix installer](https://hexdocs.pm/phoenix/installation.html) in your machine | ||
```bash | ||
mix phx.new --adapter bandit --no-tailwind --app arcane phoenix_live_view_user_management | ||
|
||
cd phoenix_live_view_user_management | ||
``` | ||
|
||
Then let's install the needed dependencies to integrate with supabase: [Supabase Potion](https://hexdocs.pm/supabase_potion). We only need to add these lines to your `deps` in `mix.exs`: | ||
|
||
```elixir | ||
defp deps do | ||
[ | ||
{:supabase_potion, "~> 0.5"}, | ||
{:supabase_gotrue, "~> 0.3"}, | ||
{:supabase_storage, "~> 0.3"}, | ||
# other dependencies | ||
] | ||
end | ||
``` | ||
|
||
Then install them with: | ||
|
||
```sh | ||
mix deps.get | ||
``` | ||
|
||
And finally we want to save the environment variables in a `.env`. | ||
All we need are the API URL and the `anon` key that you copied [earlier](#get-the-api-keys). | ||
|
||
```bash .env | ||
export SUPABASE_URL="YOUR_SUPABASE_URL" | ||
export SUPABASE_KEY="YOUR_SUPABASE_ANON_KEY" | ||
``` | ||
|
||
These variables will be exposed on the browser, and that's completely fine since we have [Row Level Security](/docs/guides/auth#row-level-security) enabled on our Database. | ||
Amazing thing about [NuxtSupabase](https://supabase.nuxtjs.org/) is that setting environment variables is all we need to do in order to start using Supabase. | ||
No need to initialize Supabase. The library will take care of it automatically. | ||
|
||
### App styling (optional) | ||
|
||
An optional step is to update the CSS file `assets/main.css` to make the app look nice. | ||
You can find the full contents of this file [here](https://github.com/zoedsoupe/supabase-ex/blob/main/examples/user_managment/phoenix_live_view_user_management/assets/css/app.css). | ||
|
||
### Set up Auth component | ||
|
||
TODO | ||
|
||
### User state | ||
|
||
TODO | ||
|
||
### Account component | ||
|
||
TODO | ||
|
||
### Launch! | ||
|
||
TODO | ||
|
||
Once that's done, run this in a terminal window: | ||
|
||
```bash | ||
iex -S mix phx.server | ||
``` | ||
|
||
And then open the browser to [localhost:4000](http://localhost:4000) and you should see the completed app. | ||
|
||
![Supabase Phoenix LiveView](https://supabase.com/docs/img/supabase-vue-3-demo.png) | ||
|
||
## Bonus: Profile photos | ||
|
||
Every Supabase project is configured with [Storage](https://supabase.com//docs/guides/storage) for managing large files like photos and videos. | ||
|
||
### Create an upload widget | ||
|
||
TODO | ||
|
||
### Add the new widget | ||
|
||
TODO | ||
|
||
That is it! You should now be able to upload a profile photo to Supabase Storage and you have a fully functional application. |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
# Use Supabase with Phoenix LiveView | ||
|
||
Learn how to create a LiveView project and connect it to your Supabase Postgres database. | ||
|
||
## 1. Create a Phoenix LiveView Project | ||
|
||
Make sure your Elixir and Phoenix installer versions are up to date, then use `mix phx.new` to scaffold a new LiveView project. Postgresql is the default database for Phoenix apps. | ||
|
||
Go to the [Phoenix docs](https://phoenixframework.org) for more details. | ||
|
||
```sh | ||
mix phx.new blog | ||
``` | ||
|
||
## 2. Set up the Postgres connection details | ||
|
||
Go to [database.new](https://database.new/) and create a new Supabase project. Save your database password securely. | ||
|
||
When your project is up and running, navigate to the [database settings](https://supabase.com/dashboard/project/_/settings/database) to find the URI connection string. Make sure **Use connection pooling** is checked and **Session mode** is selected. Then copy the URI. Replace the password placeholder with your saved database password. | ||
|
||
> [!INFO] | ||
> If your network supports IPv6 connections, you can also use the direct connection string. Uncheck **Use connection pooling** and copy the new URI. | ||
For the production environment, you can set up this env var on your `config/runtime.exs` | ||
```sh | ||
export DATABASE_URL=ecto://postgres.xxxx:password@xxxx.pooler.supabase.com:5432/postgres | ||
``` | ||
|
||
For your local dev environment your can modify the `config/dev.exs` file to look like this (replacing placeholders with your `supabase-cli` config): | ||
|
||
```elixir | ||
# config/dev.exs | ||
|
||
import Config | ||
|
||
config :blog, Blog.Repo, | ||
hostname: "localhost", | ||
port: 54322, # default supabase-cli postgres port | ||
username: "postgres", | ||
password: "postgres", | ||
database: "postgres" | ||
|
||
# other configs | ||
``` | ||
|
||
## 3. Create and run a database migration | ||
|
||
Phoenix LiveView includes [Ecto](https://hexdocs.pm/ecto) as the data mapping and database schema magement tool (aka ORM in other stacks) as well as database migration tooling which generates the SQL migration files for you. | ||
|
||
Create an example `Article` model and generate the migration files. | ||
|
||
```sh | ||
mix phx.gen.schema Posts.Article articles title:string views:integer | ||
mix ecto.migrate | ||
``` | ||
|
||
The first argument is the schema module followed by its plural name (used as the table name). | ||
|
||
The generated schema above will contain: | ||
- a schema file in `lib/blog/posts/article.ex`, with a articles table | ||
- a migration file for the repository | ||
|
||
More information on the [mix phx.new.schema task documentation](https://hexdocs.pm/phoenix/Mix.Tasks.Phx.Gen.Schema.html) | ||
|
||
## 4. Use the Model to interact with the database | ||
|
||
You can use the included Phoenix console to interact with the database. For example, you can create new entries or list all entries in a Model's table. | ||
|
||
```sh | ||
iex -S mix | ||
``` | ||
|
||
```iex | ||
article = %Blog.Posts.Article{title: "Hello Phoenix", body: "I am on Phoenix!"} | ||
Blog.Repo.insert!(article) # Saves the entry to the database | ||
Blog.Repo.all(Blog.Posts.Article) # Lists all the entries of a model in the database | ||
``` | ||
|
||
## 5. Start the app | ||
|
||
Run the development server. Go to [http://127.0.0.1:4000](http://127.0.0.1:4000) in a browser to see your application running. | ||
|
||
```sh | ||
iex -S mix phx.server | ||
``` | ||
|
||
> This command also starts an iex session (REPL) while staring the web server |