From abebd998599cfc718797a56d2a74254e7f7a1f59 Mon Sep 17 00:00:00 2001 From: dshukertjr <18113850+dshukertjr@users.noreply.github.com> Date: Mon, 19 Jul 2021 22:25:43 +0900 Subject: [PATCH 01/17] feat: Created with-flutter.mdx and started the guide --- web/docs/guides/with-flutter.mdx | 560 +++++++++++++++++++++++++++++++ 1 file changed, 560 insertions(+) create mode 100644 web/docs/guides/with-flutter.mdx diff --git a/web/docs/guides/with-flutter.mdx b/web/docs/guides/with-flutter.mdx new file mode 100644 index 00000000000..c4749a062ce --- /dev/null +++ b/web/docs/guides/with-flutter.mdx @@ -0,0 +1,560 @@ +--- +id: with-flutter +title: "Quickstart: Flutter" +description: Learn how to use Supabase in your Flutter App. +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +## Intro + +This example provides the steps to build a simple user management app (from scratch!) using Supabase and Flutter. It includes: + +- Supabase [Database](/docs/guides/database): a Postgres database for storing your user data. +- Supabase [Auth](/docs/guides/auth): users can sign in with magic links (no passwords, only email). +- Supabase [Storage](/docs/guides/storage): users can upload a photo. +- [Row Level Security](/docs/guides/auth#row-level-security): data is protected so that individuals can only access their own data. +- Instant [APIs](/docs/guides/api): APIs will be automatically generated when you create your database tables. + +By the end of this guide you'll have an app which allows users to login and update some basic profile details: + +![Supabase User Management example](/img/user-management-demo.png) + + + +## Project set up + +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. Go to [app.supabase.io](https://app.supabase.io). +1. Click on "New Project". +1. Enter your project details. +1. Wait for the new database to launch. + + +### Set up the database schema + +Now we are going to set up the database schema. We can use the "User Management Starter" quickstart in the SQL Editor, +or you can just copy/paste the SQL from below and run it yourself. + + + + +```sh +1. Go to the "SQL" section. +2. Click "User Management Starter". +4. Click "Run". +``` + + + + + + +```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 ( auth.uid() = id ); + +create policy "Users can update own profile." + on profiles for update + using ( 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' ); + +``` + + + + + +### 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 URL and `anon` key from the API settings. + + + + +```sh +1. Go to the "Settings" section. +2. Click "API" in the sidebar. +3. Find your API URL in this page. +4. Find your "anon" key on this page. +``` + + + + + + +## Building the App + +Let's start building the Flutter app from scratch. + +### Initialize a Flutter app + +We can use [`flutter create`](https://flutter.dev/docs/get-started/test-drive) to initialize +an app called `supabase_quickstart`: + +```bash +flutter create supabase_quickstart +``` + +Then let's install the only additional dependency: [supabase-flutter](https://github.com/supabase/supabase-flutter) + +Open the app and copy and paste the following inside `pubspec.yaml` under `dependencies`. + +```yaml +supabase_flutter: ^0.0.3 +``` + +Run `flutter pub get` to install the dependencies. + +Now that we have the dependencies installed let's initialize the Supabase client inside our `main` function with the API credentials that you copied [earlier](#get-the-api-keys). +These variables will be exposed on the app, and that's completely fine since we have +[Row Level Security](/docs/guides/auth#row-level-security) enabled on our Database. + +```dart title="lib/main.dart" +void main() { + WidgetsFlutterBinding.ensureInitialized(); + + Supabase.initialize( + url: YOUR_SUPABASE_URL, + anonKey: YOUR_SUPABASE_ANNON_KEY, + ); + runApp(MyApp()); +} +``` + + + +### Set up a Login widget + +Let's create a Flutter widget to manage logins and sign ups. + +Let's set up a React component to manage logins and sign ups. +We'll use Magic Links, so users can sign in with their email without using passwords. + +```jsx title="components/Auth.js" +import { useState } from 'react' +import { supabase } from '../utils/supabaseClient' + +export default function Auth() { + const [loading, setLoading] = useState(false) + const [email, setEmail] = useState('') + + const handleLogin = async (email) => { + try { + setLoading(true) + const { error } = await supabase.auth.signIn({ email }) + if (error) throw error + alert('Check your email for the login link!') + } catch (error) { + alert(error.error_description || error.message) + } finally { + setLoading(false) + } + } + + return ( +
+
+

Supabase + Next.js

+

Sign in via magic link with your email below

+
+ setEmail(e.target.value)} + /> +
+
+ +
+
+
+ ) +} +``` + +### Account page + +After a user is signed in we can allow them to edit their profile details and manage their account. + +Let's create a new component for that called `Account.js`. + +```jsx title="components/Account.js" +import { useState, useEffect } from 'react' +import { supabase } from '../utils/supabaseClient' + +export default function Account({ session }) { + const [loading, setLoading] = useState(true) + const [username, setUsername] = useState(null) + const [website, setWebsite] = useState(null) + const [avatar_url, setAvatarUrl] = useState(null) + + useEffect(() => { + getProfile() + }, [session]) + + async function getProfile() { + try { + setLoading(true) + const user = supabase.auth.user() + + let { data, error, status } = await supabase + .from('profiles') + .select(`username, website, avatar_url`) + .eq('id', user.id) + .single() + + if (error && status !== 406) { + throw error + } + + if (data) { + setUsername(data.username) + setWebsite(data.website) + setAvatarUrl(data.avatar_url) + } + } catch (error) { + alert(error.message) + } finally { + setLoading(false) + } + } + + async function updateProfile({ username, website, avatar_url }) { + try { + setLoading(true) + const user = supabase.auth.user() + + const updates = { + id: user.id, + username, + website, + avatar_url, + updated_at: new Date(), + } + + let { error } = await supabase.from('profiles').upsert(updates, { + returning: 'minimal', // Don't return the value after inserting + }) + + if (error) { + throw error + } + } catch (error) { + alert(error.message) + } finally { + setLoading(false) + } + } + + return ( +
+
+ + +
+
+ + setUsername(e.target.value)} + /> +
+
+ + setWebsite(e.target.value)} + /> +
+ +
+ +
+ +
+ +
+
+ ) +} + +``` + + + +### Launch! + +Now that we have all the components in place, let's update `pages/index.js`: + +```jsx title="pages/index.js" +import { useState, useEffect } from 'react' +import { supabase } from '../utils/supabaseClient' +import Auth from '../components/Auth' +import Account from '../components/Account' + +export default function Home() { + const [session, setSession] = useState(null) + + useEffect(() => { + setSession(supabase.auth.session()) + + supabase.auth.onAuthStateChange((_event, session) => { + setSession(session) + }) + }, []) + + return ( +
+ {!session ? : } +
+ ) +} +``` + +Once that's done, run this in a terminal window: + +```bash +npm run dev +``` + +And then open the browser to [localhost:3000](http://localhost:3000) and you should see the completed app. + + +![Supabase User demo](/img/supabase-react-demo.png) + +## Bonus: Profile photos + +Every Supabase project is configured with [Storage](/docs/guides/storage) for managing large files like +photos and videos. + +### Create an upload widget + +Let's create an avatar for the user so that they can upload a profile photo. +We can start by creating a new component: + +```jsx title="components/Avatar.js" +import { useEffect, useState } from 'react' +import { supabase } from '../utils/supabaseClient' + +export default function Avatar({ url, size, onUpload }) { + const [avatarUrl, setAvatarUrl] = useState(null) + const [uploading, setUploading] = useState(false) + + useEffect(() => { + if (url) downloadImage(url) + }, [url]) + + async function downloadImage(path) { + try { + const { data, error } = await supabase.storage.from('avatars').download(path) + if (error) { + throw error + } + const url = URL.createObjectURL(data) + setAvatarUrl(url) + } catch (error) { + console.log('Error downloading image: ', error.message) + } + } + + + async function uploadAvatar(event) { + try { + setUploading(true) + + if (!event.target.files || event.target.files.length === 0) { + throw new Error('You must select an image to upload.') + } + + const file = event.target.files[0] + const fileExt = file.name.split('.').pop() + const fileName = `${Math.random()}.${fileExt}` + const filePath = `${fileName}` + + let { error: uploadError } = await supabase.storage + .from('avatars') + .upload(filePath, file) + + if (uploadError) { + throw uploadError + } + + onUpload(filePath) + } catch (error) { + alert(error.message) + } finally { + setUploading(false) + } + } + + return ( +
+ {avatarUrl ? ( + Avatar + ) : ( +
+ )} +
+ + +
+
+ ) +} +``` + + +### Add the new widget + +And then we can add the widget to the Account page: + + +```jsx title="components/Account.js" +// Import the new component +import Avatar from './Avatar' + +// ... + +return ( +
+ {/* Add to the body */} + { + setAvatarUrl(url) + updateProfile({ username, website, avatar_url: url }) + }} + /> + {/* ... */} +
+) + +``` + +## Next steps + +At this stage you have a fully functional application! + +- Got a question? [Ask here](https://github.com/supabase/supabase/discussions). +- Sign in: [app.supabase.io](https://app.supabase.io) From 7d4b72f63778055ca9e8fdc707db3261dd3c28b9 Mon Sep 17 00:00:00 2001 From: Inian Parameshwaran Date: Wed, 31 Mar 2021 16:32:03 +0530 Subject: [PATCH 02/17] Adds storage server to self hosting setup --- docker/README.md | 15 ++-- docker/docker-compose.yml | 108 +++++++++++------------- docker/dockerfiles/kong/kong.yml | 10 +++ docker/dockerfiles/postgres/Dockerfile | 1 + docker/postgres/storage-schema.sql | 111 +++++++++++++++++++++++++ 5 files changed, 181 insertions(+), 64 deletions(-) create mode 100644 docker/postgres/storage-schema.sql diff --git a/docker/README.md b/docker/README.md index 4b0f64e1546..041594405a7 100644 --- a/docker/README.md +++ b/docker/README.md @@ -3,7 +3,10 @@ You can run Supabase on your local machine or a server using `docker-compose`. For a more secure setup to use on a server (e.g. using HTTPS), have a look at the *supabase-traefik* setup. -## Configuration +Update the docker-compose file with your valid AWS_SECRET_ACCESS_KEY and AWS_ACCESS_KEY_ID in the storage section. The key must have permissions to `s3:PutObject , s3:GetObject, s3:DeleteObject` in the bucket you have chosen. +In production, PGRST_JWT_SECRET and derived keys from the JWT secret like ANON_KEY need to be changed to different values. + +You can run Supabase on your local machine using `docker-compose`: Add your passwords to the .env file. For better customization and security, please make sure you read the [self-hosting guide](https://supabase.io/docs/guides/self-hosting#running-supabase). @@ -27,7 +30,9 @@ const supabase = createClient(SUPABASE_URL, SUPABASE_KEY) Accessing the services directly: - Kong: http://localhost:8000 - - GoTrue: http://localhost:8000/auth/v1/?apikey= - - PostgREST: http://localhost:8000/rest/v1/?apikey= - - Realtime: http://localhost:8000/realtime/v1/?apikey= -- Postgres: http://localhost:5432 \ No newline at end of file + - GoTrue: http://localhost:8000/auth/v1/ + - PostgREST: http://localhost:8000/rest/v1/ + - Realtime: http://localhost:8000/realtime/v1/ + - Supabase: http://localhost:8000/storage/v1 +- Postgres: http://localhost:5432 + diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 194050ee191..513e427a129 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -17,67 +17,57 @@ services: - ${AUTH_PORT} depends_on: - db - environment: - GOTRUE_JWT_SECRET: ${JWT_SECRET} - GOTRUE_JWT_EXP: 3600 - GOTRUE_JWT_DEFAULT_GROUP_NAME: authenticated - GOTRUE_DB_DRIVER: postgres - DB_NAMESPACE: auth - API_EXTERNAL_URL: localhost - GOTRUE_API_HOST: 0.0.0.0 - PORT: ${AUTH_PORT} - - GOTRUE_SMTP_HOST: ${SMTP_HOST} - GOTRUE_SMTP_PORT: ${SMTP_PORT} - GOTRUE_SMTP_USER: ${SMTP_USER} - GOTRUE_SMTP_PASS: ${SMTP_PASS} - - GOTRUE_DISABLE_SIGNUP: 'false' - GOTRUE_SITE_URL: localhost - GOTRUE_MAILER_AUTOCONFIRM: 'true' - GOTRUE_LOG_LEVEL: DEBUG - GOTRUE_OPERATOR_TOKEN: ${OPERATOR_TOKEN} - DATABASE_URL: 'postgres://postgres:${POSTGRES_PASSWORD}@db:${POSTGRES_PORT}/postgres?sslmode=disable' - - rest: - container_name: supabase-rest - image: postgrest/postgrest:latest - ports: - - ${REST_PORT}:3000 - depends_on: + restart: always + environment: + PGRST_DB_URI: postgres://postgres:postgres@db:5432/postgres + PGRST_DB_SCHEMA: public, storage + PGRST_DB_ANON_ROLE: postgres + PGRST_JWT_SECRET: super-secret-jwt-token-with-at-least-32-characters-long + realtime: + image: supabase/realtime:latest + ports: + - '4000:4000' + depends_on: - db - restart: always - environment: - PGRST_DB_URI: postgres://postgres:${POSTGRES_PASSWORD}@db:${POSTGRES_PORT}/postgres - PGRST_DB_SCHEMA: public - PGRST_DB_ANON_ROLE: anon - PGRST_JWT_SECRET: ${JWT_SECRET} - realtime: - container_name: supabase-realtime - image: supabase/realtime:latest - ports: - - ${REALTIME_PORT} - depends_on: + restart: on-failure + environment: + DB_HOST: db + DB_NAME: postgres + DB_USER: postgres + DB_PASSWORD: postgres + DB_PORT: 5432 + PORT: 4000 + HOSTNAME: localhost + # Disable JWT Auth locally. The JWT_SECRET will be ignored. + SECURE_CHANNELS: 'false' + JWT_SECRET: super-secret-jwt-token-with-at-least-32-characters-long + storage: + image: supabase/storage-api:v0.1.4 + ports: + - '5000:5000' + depends_on: - db - restart: on-failure - environment: - DB_HOST: db - DB_NAME: postgres - DB_USER: postgres - DB_PASSWORD: ${POSTGRES_PASSWORD} - DB_PORT: ${POSTGRES_PORT} - PORT: ${REALTIME_PORT} - HOSTNAME: localhost - # Disable JWT Auth locally. The JWT_SECRET will be ignored. - SECURE_CHANNELS: 'false' - JWT_SECRET: ${JWT_SECRET} - db: - container_name: supabase-db - build: - context: ./dockerfiles/postgres - ports: - - ${POSTGRES_PORT}:${POSTGRES_PORT} - command: + - rest + restart: on-failure + environment: + ANON_KEY: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTYxMzUzMTk4NSwiZXhwIjoxOTI5MTA3OTg1fQ.ReNhHIoXIOa-8tL1DO3e26mJmOTnYuvdgobwIYGzrLQ + SERVICE_KEY: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoic2VydmljZV9yb2xlIiwiaWF0IjoxNjEzNTMxOTg1LCJleHAiOjE5MjkxMDc5ODV9.FhK1kZdHmWdCIEZELt0QDCw6FIlCS8rVmp4RzaeI2LM + PROJECT_REF: bjwdssmqcnupljrqypxz # can be any random string + REGION: us-east-1 # region where your bucket is located + POSTGREST_URL: http://rest:3000 + GLOBAL_S3_BUCKET: supa-storage-testing # name of s3 bucket where you want to store objects + PGRST_JWT_SECRET: super-secret-jwt-token-with-at-least-32-characters-long + DATABASE_URL: postgres://postgres:postgres@db:5432/postgres + PGOPTIONS: "-c search_path=storage" + AWS_ACCESS_KEY_ID: replace-with-your-aws-key + AWS_SECRET_ACCESS_KEY: replace-with-your-aws-secret + FILE_SIZE_LIMIT: 52428800 + db: + build: + context: ./postgres + ports: + - 5432:5432 + command: - postgres - -c - wal_level=logical diff --git a/docker/dockerfiles/kong/kong.yml b/docker/dockerfiles/kong/kong.yml index 1adfb5c8c58..659d804783e 100644 --- a/docker/dockerfiles/kong/kong.yml +++ b/docker/dockerfiles/kong/kong.yml @@ -39,6 +39,16 @@ services: - name: key-auth config: hide_credentials: true +- name: storage-v1 + _comment: 'Storage: /storage/v1/* -> http://storage-api:5000/*' + url: http://storage:5000/ + routes: + - name: storage-v1-all + strip_path: true + paths: + - /storage/v1/ + plugins: + - name: cors consumers: - username: 'anon-key' keyauth_credentials: diff --git a/docker/dockerfiles/postgres/Dockerfile b/docker/dockerfiles/postgres/Dockerfile index cbec306808c..cd03b29b241 100644 --- a/docker/dockerfiles/postgres/Dockerfile +++ b/docker/dockerfiles/postgres/Dockerfile @@ -2,6 +2,7 @@ FROM supabase/postgres:0.13.0 COPY 00-initial-schema.sql /docker-entrypoint-initdb.d/00-initial-schema.sql COPY auth-schema.sql /docker-entrypoint-initdb.d/auth-schema.sql +COPY storage-schema.sql /docker-entrypoint-initdb.d/storage-schema.sql # Build time defaults ARG build_POSTGRES_DB=postgres diff --git a/docker/postgres/storage-schema.sql b/docker/postgres/storage-schema.sql new file mode 100644 index 00000000000..c879c6b6234 --- /dev/null +++ b/docker/postgres/storage-schema.sql @@ -0,0 +1,111 @@ +CREATE SCHEMA IF NOT EXISTS storage AUTHORIZATION postgres; + +grant usage on schema storage to postgres, anon, authenticated, service_role; +alter default privileges in schema storage grant all on tables to postgres, anon, authenticated, service_role; +alter default privileges in schema storage grant all on functions to postgres, anon, authenticated, service_role; +alter default privileges in schema storage grant all on sequences to postgres, anon, authenticated, service_role; + +DROP TABLE IF EXISTS "storage"."buckets"; +CREATE TABLE "storage"."buckets" ( + "id" text not NULL, + "name" text NOT NULL, + "owner" uuid, + "created_at" timestamptz DEFAULT now(), + "updated_at" timestamptz DEFAULT now(), + CONSTRAINT "buckets_owner_fkey" FOREIGN KEY ("owner") REFERENCES "auth"."users"("id"), + PRIMARY KEY ("id") +); +CREATE UNIQUE INDEX "bname" ON "storage"."buckets" USING BTREE ("name"); + +DROP TABLE IF EXISTS "storage"."objects"; +CREATE TABLE "storage"."objects" ( + "id" uuid NOT NULL DEFAULT extensions.uuid_generate_v4(), + "bucket_id" text, + "name" text, + "owner" uuid, + "created_at" timestamptz DEFAULT now(), + "updated_at" timestamptz DEFAULT now(), + "last_accessed_at" timestamptz DEFAULT now(), + "metadata" jsonb, + CONSTRAINT "objects_bucketId_fkey" FOREIGN KEY ("bucket_id") REFERENCES "storage"."buckets"("id"), + CONSTRAINT "objects_owner_fkey" FOREIGN KEY ("owner") REFERENCES "auth"."users"("id"), + PRIMARY KEY ("id") +); +CREATE UNIQUE INDEX "bucketid_objname" ON "storage"."objects" USING BTREE ("bucket_id","name"); +CREATE INDEX name_prefix_search ON storage.objects(name text_pattern_ops); + +ALTER TABLE storage.objects ENABLE ROW LEVEL SECURITY; + +CREATE OR REPLACE FUNCTION storage.foldername(name text) + RETURNS text[] + LANGUAGE plpgsql +AS $function$ +DECLARE +_parts text[]; +BEGIN + select string_to_array(name, '/') into _parts; + return _parts[1:array_length(_parts,1)-1]; +END +$function$; + +CREATE OR REPLACE FUNCTION storage.filename(name text) + RETURNS text + LANGUAGE plpgsql +AS $function$ +DECLARE +_parts text[]; +BEGIN + select string_to_array(name, '/') into _parts; + return _parts[array_length(_parts,1)]; +END +$function$; + +CREATE OR REPLACE FUNCTION storage.extension(name text) + RETURNS text + LANGUAGE plpgsql +AS $function$ +DECLARE +_parts text[]; +_filename text; +BEGIN + select string_to_array(name, '/') into _parts; + select _parts[array_length(_parts,1)] into _filename; + return split_part(_filename, '.', 2); +END +$function$; + +CREATE OR REPLACE FUNCTION storage.search(prefix text, bucketname text, limits int DEFAULT 100, levels int DEFAULT 1, offsets int DEFAULT 0) + RETURNS TABLE ( + name text, + id uuid, + updated_at TIMESTAMPTZ, + created_at TIMESTAMPTZ, + last_accessed_at TIMESTAMPTZ, + metadata jsonb + ) + LANGUAGE plpgsql +AS $function$ +DECLARE +_bucketId text; +BEGIN + select buckets."id" from buckets where buckets.name=bucketname limit 1 into _bucketId; + return query + with files_folders as ( + select ((string_to_array(objects.name, '/'))[levels]) as folder + from objects + where objects.name ilike prefix || '%' + and bucket_id = _bucketId + GROUP by folder + limit limits + offset offsets + ) + select files_folders.folder as name, objects.id, objects.updated_at, objects.created_at, objects.last_accessed_at, objects.metadata from files_folders + left join objects + on prefix || files_folders.folder = objects.name + where objects.id is null or objects.bucket_id=_bucketId; +END +$function$; + +GRANT ALL PRIVILEGES ON SCHEMA storage TO postgres; +GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA storage TO postgres; +GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA storage TO postgres; \ No newline at end of file From 635dab60dcdc8115a6a72d7ee58580cf7e5d4225 Mon Sep 17 00:00:00 2001 From: Inian Date: Tue, 20 Jul 2021 21:17:02 +0800 Subject: [PATCH 03/17] storage working with a file system backend --- docker/README.md | 15 +- docker/docker-compose.yml | 135 +++++++++++------- .../postgres/storage-schema.sql | 0 3 files changed, 90 insertions(+), 60 deletions(-) rename docker/{ => dockerfiles}/postgres/storage-schema.sql (100%) diff --git a/docker/README.md b/docker/README.md index 041594405a7..4b0f64e1546 100644 --- a/docker/README.md +++ b/docker/README.md @@ -3,10 +3,7 @@ You can run Supabase on your local machine or a server using `docker-compose`. For a more secure setup to use on a server (e.g. using HTTPS), have a look at the *supabase-traefik* setup. -Update the docker-compose file with your valid AWS_SECRET_ACCESS_KEY and AWS_ACCESS_KEY_ID in the storage section. The key must have permissions to `s3:PutObject , s3:GetObject, s3:DeleteObject` in the bucket you have chosen. -In production, PGRST_JWT_SECRET and derived keys from the JWT secret like ANON_KEY need to be changed to different values. - -You can run Supabase on your local machine using `docker-compose`: +## Configuration Add your passwords to the .env file. For better customization and security, please make sure you read the [self-hosting guide](https://supabase.io/docs/guides/self-hosting#running-supabase). @@ -30,9 +27,7 @@ const supabase = createClient(SUPABASE_URL, SUPABASE_KEY) Accessing the services directly: - Kong: http://localhost:8000 - - GoTrue: http://localhost:8000/auth/v1/ - - PostgREST: http://localhost:8000/rest/v1/ - - Realtime: http://localhost:8000/realtime/v1/ - - Supabase: http://localhost:8000/storage/v1 -- Postgres: http://localhost:5432 - + - GoTrue: http://localhost:8000/auth/v1/?apikey= + - PostgREST: http://localhost:8000/rest/v1/?apikey= + - Realtime: http://localhost:8000/realtime/v1/?apikey= +- Postgres: http://localhost:5432 \ No newline at end of file diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 513e427a129..a8d17f1138f 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -17,57 +17,92 @@ services: - ${AUTH_PORT} depends_on: - db - restart: always - environment: - PGRST_DB_URI: postgres://postgres:postgres@db:5432/postgres - PGRST_DB_SCHEMA: public, storage - PGRST_DB_ANON_ROLE: postgres - PGRST_JWT_SECRET: super-secret-jwt-token-with-at-least-32-characters-long - realtime: - image: supabase/realtime:latest - ports: - - '4000:4000' - depends_on: + environment: + GOTRUE_JWT_SECRET: ${JWT_SECRET} + GOTRUE_JWT_EXP: 3600 + GOTRUE_JWT_DEFAULT_GROUP_NAME: authenticated + GOTRUE_DB_DRIVER: postgres + DB_NAMESPACE: auth + API_EXTERNAL_URL: localhost + GOTRUE_API_HOST: 0.0.0.0 + PORT: ${AUTH_PORT} + + GOTRUE_SMTP_HOST: ${SMTP_HOST} + GOTRUE_SMTP_PORT: ${SMTP_PORT} + GOTRUE_SMTP_USER: ${SMTP_USER} + GOTRUE_SMTP_PASS: ${SMTP_PASS} + + GOTRUE_DISABLE_SIGNUP: 'false' + GOTRUE_SITE_URL: localhost + GOTRUE_MAILER_AUTOCONFIRM: 'true' + GOTRUE_LOG_LEVEL: DEBUG + GOTRUE_OPERATOR_TOKEN: ${OPERATOR_TOKEN} + DATABASE_URL: 'postgres://postgres:${POSTGRES_PASSWORD}@db:${POSTGRES_PORT}/postgres?sslmode=disable' + + rest: + container_name: supabase-rest + image: postgrest/postgrest:latest + ports: + - ${REST_PORT}:3000 + depends_on: - db - restart: on-failure - environment: - DB_HOST: db - DB_NAME: postgres - DB_USER: postgres - DB_PASSWORD: postgres - DB_PORT: 5432 - PORT: 4000 - HOSTNAME: localhost - # Disable JWT Auth locally. The JWT_SECRET will be ignored. - SECURE_CHANNELS: 'false' - JWT_SECRET: super-secret-jwt-token-with-at-least-32-characters-long - storage: - image: supabase/storage-api:v0.1.4 - ports: - - '5000:5000' - depends_on: + restart: always + environment: + PGRST_DB_URI: postgres://postgres:${POSTGRES_PASSWORD}@db:${POSTGRES_PORT}/postgres + PGRST_DB_SCHEMA: public, storage + PGRST_DB_ANON_ROLE: anon + PGRST_JWT_SECRET: ${JWT_SECRET} + + realtime: + container_name: supabase-realtime + image: supabase/realtime:latest + ports: + - ${REALTIME_PORT} + depends_on: - db - - rest - restart: on-failure - environment: - ANON_KEY: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTYxMzUzMTk4NSwiZXhwIjoxOTI5MTA3OTg1fQ.ReNhHIoXIOa-8tL1DO3e26mJmOTnYuvdgobwIYGzrLQ - SERVICE_KEY: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoic2VydmljZV9yb2xlIiwiaWF0IjoxNjEzNTMxOTg1LCJleHAiOjE5MjkxMDc5ODV9.FhK1kZdHmWdCIEZELt0QDCw6FIlCS8rVmp4RzaeI2LM - PROJECT_REF: bjwdssmqcnupljrqypxz # can be any random string - REGION: us-east-1 # region where your bucket is located - POSTGREST_URL: http://rest:3000 - GLOBAL_S3_BUCKET: supa-storage-testing # name of s3 bucket where you want to store objects - PGRST_JWT_SECRET: super-secret-jwt-token-with-at-least-32-characters-long - DATABASE_URL: postgres://postgres:postgres@db:5432/postgres - PGOPTIONS: "-c search_path=storage" - AWS_ACCESS_KEY_ID: replace-with-your-aws-key - AWS_SECRET_ACCESS_KEY: replace-with-your-aws-secret - FILE_SIZE_LIMIT: 52428800 - db: - build: - context: ./postgres - ports: - - 5432:5432 - command: + restart: on-failure + environment: + DB_HOST: db + DB_NAME: postgres + DB_USER: postgres + DB_PASSWORD: ${POSTGRES_PASSWORD} + DB_PORT: ${POSTGRES_PORT} + PORT: ${REALTIME_PORT} + HOSTNAME: localhost + # Disable JWT Auth locally. The JWT_SECRET will be ignored. + SECURE_CHANNELS: 'false' + JWT_SECRET: ${JWT_SECRET} + + storage: + image: supabase/storage-api:v0.8.3 + ports: + - '5000:5000' + depends_on: + - db + - rest + restart: on-failure + environment: + ANON_KEY: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJzdXBhYmFzZSIsImlhdCI6MTYwMzk2ODgzNCwiZXhwIjoxNjkwNDQzMTM1LCJhdWQiOiIiLCJzdWIiOiIiLCJSb2xlIjoiYW5vbiIsImp0aSI6ImQ1N2ZkMjFlLTNkYjQtNDk3YS1hNGViLTI4ZDY3Yzg2NjEwMiJ9.YySz_BoYxYco0b2aP3iBMt-dVUqC6RpnQiSb4Zt-L-o + SERVICE_KEY: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJzdXBhYmFzZSIsImlhdCI6MTYwMzk2ODgzNCwiZXhwIjoxNjkwNDQzMTM1LCJhdWQiOiIiLCJyb2xlIjoic2VydmljZV9yb2xlIiwianRpIjoiOTk4MzJiYmItNDdhNS00NzJhLTgxMDQtYzY4ZGVjZDQyZDVlIn0._DToQdxDcSLsp3tPpacsxswv0p1KRti0QOTmnbfs5JY + PROJECT_REF: bjwdssmqcnupljrqypxz # can be any random string + POSTGREST_URL: http://rest:3000 + PGRST_JWT_SECRET: ${JWT_SECRET} + DATABASE_URL: postgres://postgres:${POSTGRES_PASSWORD}@db:${POSTGRES_PORT}/postgres + PGOPTIONS: "-c search_path=storage" + FILE_SIZE_LIMIT: 52428800 + REGION: us-east-1 # region where your bucket is located + GLOBAL_S3_BUCKET: supa-storage-testing # name of s3 bucket where you want to store objects + # AWS_ACCESS_KEY_ID: replace-with-your-aws-key + # AWS_SECRET_ACCESS_KEY: replace-with-your-aws-secret + STORAGE_BACKEND: file + FILE_STORAGE_BACKEND_PATH: /var/data/storage + db: + container_name: supabase-db + build: + context: ./dockerfiles/postgres + ports: + - ${POSTGRES_PORT}:${POSTGRES_PORT} + command: - postgres - -c - wal_level=logical @@ -75,4 +110,4 @@ services: POSTGRES_DB: postgres POSTGRES_USER: postgres POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - POSTGRES_PORT: ${POSTGRES_PORT} + POSTGRES_PORT: ${POSTGRES_PORT} \ No newline at end of file diff --git a/docker/postgres/storage-schema.sql b/docker/dockerfiles/postgres/storage-schema.sql similarity index 100% rename from docker/postgres/storage-schema.sql rename to docker/dockerfiles/postgres/storage-schema.sql From 424483fac4ae467f8093a71798539e44e5729ca3 Mon Sep 17 00:00:00 2001 From: Inian Date: Tue, 20 Jul 2021 21:17:48 +0800 Subject: [PATCH 04/17] storage depends on nightly version of postgrest else match call for update is not working --- docker/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index a8d17f1138f..e0c4af21e53 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -41,7 +41,7 @@ services: rest: container_name: supabase-rest - image: postgrest/postgrest:latest + image: postgrest/postgrest:nightly-2021-03-05-19-03-d3a8b5f ports: - ${REST_PORT}:3000 depends_on: From ffdde846aadfd0fbb52b0eb34fb3b3da30953a34 Mon Sep 17 00:00:00 2001 From: Beng Eu Date: Wed, 21 Jul 2021 12:12:55 +0800 Subject: [PATCH 05/17] Document from.upload() and from.update() workaround for React Native --- web/spec/supabase.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/web/spec/supabase.yml b/web/spec/supabase.yml index b6e3a05e9cc..45f4e397478 100644 --- a/web/spec/supabase.yml +++ b/web/spec/supabase.yml @@ -986,6 +986,7 @@ pages: - Policy permissions required: - `buckets` permissions: none - `objects` permissions: `insert` + - For React Native, using either `Blob`, `File` or `FormData` does not work as intended. Upload file using `ArrayBuffer` from base64 file data instead, see example below. examples: - name: Upload file isSpotlight: true @@ -1000,6 +1001,18 @@ pages: upsert: false }) ``` + - name: Upload file using `ArrayBuffer` from base64 file data + js: | + ```js + import {decode} from 'base64-arraybuffer' + + const { data, error } = await supabase + .storage + .from('avatars') + .upload('public/avatar1.png', decode('base64FileData'), { + contentType: 'image/png' + }) + ``` storage.from.update(): title: 'from.update()' @@ -1008,6 +1021,7 @@ pages: - Policy permissions required: - `buckets` permissions: none - `objects` permissions: `update` and `select` + - For React Native, using either `Blob`, `File` or `FormData` does not work as intended. Update file using `ArrayBuffer` from base64 file data instead, see example below. examples: - name: Update file isSpotlight: true @@ -1022,6 +1036,18 @@ pages: upsert: false }) ``` + - name: Update file using `ArrayBuffer` from base64 file data + js: | + ```js + import {decode} from 'base64-arraybuffer' + + const { data, error } = await supabase + .storage + .from('avatars') + .update('public/avatar1.png', decode('base64FileData'), { + contentType: 'image/png' + }) + ``` storage.from.move(): title: 'from.move()' From 0254f0865c901efed19739ac02e1a4db75a5e44d Mon Sep 17 00:00:00 2001 From: dshukertjr <18113850+dshukertjr@users.noreply.github.com> Date: Thu, 22 Jul 2021 08:47:16 +0900 Subject: [PATCH 06/17] chore: Finished up with flutter quick start for the most part --- web/docs/guides/with-flutter.mdx | 692 +++++++++++++++------------- web/static/img/deeplink-setting.png | Bin 0 -> 88204 bytes 2 files changed, 375 insertions(+), 317 deletions(-) create mode 100644 web/static/img/deeplink-setting.png diff --git a/web/docs/guides/with-flutter.mdx b/web/docs/guides/with-flutter.mdx index c4749a062ce..b111e7a4356 100644 --- a/web/docs/guides/with-flutter.mdx +++ b/web/docs/guides/with-flutter.mdx @@ -71,7 +71,7 @@ values={[ ```sh 1. Go to the "SQL" section. 2. Click "User Management Starter". -4. Click "Run". +3. Click "Run". ```
From 1184e8fb4f2abe6dfa2c71d10cdbd7701927c7a6 Mon Sep 17 00:00:00 2001 From: Jonathan Summers-Muir Date: Thu, 22 Jul 2021 20:48:45 +0800 Subject: [PATCH 08/17] fix: wrong date --- www/pages/beta.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/pages/beta.tsx b/www/pages/beta.tsx index 9e8abab17c6..350c3884c1f 100644 --- a/www/pages/beta.tsx +++ b/www/pages/beta.tsx @@ -118,7 +118,7 @@ const Hero = () => { Today, we're moving to Beta

From 0bb81f805873c0de828e8bd189a67025b6dd358a Mon Sep 17 00:00:00 2001 From: Scott Pritchard Date: Thu, 22 Jul 2021 14:45:49 +0100 Subject: [PATCH 09/17] Update examples.mdx Added link to self-hosting guide --- web/docs/guides/examples.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/web/docs/guides/examples.mdx b/web/docs/guides/examples.mdx index 90a84f66f7d..efde677ad7b 100644 --- a/web/docs/guides/examples.mdx +++ b/web/docs/guides/examples.mdx @@ -56,6 +56,7 @@ Build a basic Todo List with Supabase and your favorite frontend framework: - Flutter Supabase Authentication [Blog](https://www.sandromaglione.com/2021/04/24/flutter-supabase-authentication/) - Supabase in 6 minutes [Video](https://www.youtube.com/watch?v=c8DNV9yl0mg) - Let's build SupaAuth - Build an Authentication System using Supabase, Next.js and Typescript [6-part Blog Series](https://aalam.in/blog/supabase-auth-intro-setup-next) +- In-depth self-hosting guide using Nginx [Blog](https://dev.to/chronsyn/self-hosting-with-supabase-1aii) ### Example apps From 74bf8ff63d48eadd9c6f9e589f7eba5f7d605616 Mon Sep 17 00:00:00 2001 From: Inian Date: Thu, 22 Jul 2021 21:55:28 +0800 Subject: [PATCH 10/17] fix twitter links --- www/_blog/2021-07-22-supabase-launch-week-sql.mdx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/www/_blog/2021-07-22-supabase-launch-week-sql.mdx b/www/_blog/2021-07-22-supabase-launch-week-sql.mdx index 21b8f43e0b6..46c9d0a630b 100644 --- a/www/_blog/2021-07-22-supabase-launch-week-sql.mdx +++ b/www/_blog/2021-07-22-supabase-launch-week-sql.mdx @@ -1,5 +1,5 @@ --- -title: "Supabase Launch Week II: The SQL" +title: 'Supabase Launch Week II: The SQL' description: Five days of Supabase. Again. author: paul_copplestone author_url: https://github.com/kiwicopple @@ -15,7 +15,7 @@ toc_depth: 2 In March, Supabase held a [Launch Week](https://supabase.io/blog/2021/03/25/launch-week) where we launched a new product/feature every day for a week. -It may seem crazy to do another launch week just four months later, but we couldn't give up on a good pun, so get ready for **Launch Week II: the SQL**. +It may seem crazy to do another launch week just four months later, but we couldn't give up on a good pun, so get ready for **Launch Week II: the SQL**. ## What to expect @@ -35,7 +35,7 @@ One of the best things about building Supabase is the community. We're even luck ### Where? -Blog post coming soon. Follow our [Twitter](twitter.com/supabase) to get notified immediately. +Blog post coming soon. Follow our [Twitter](https://twitter.com/supabase) to get notified immediately. ## Tuesday 27 July: Auth v2 @@ -51,7 +51,7 @@ What's cooler than Arnie in the 90's? Passwordless logins. We've [already](https ### Where? -Blog post coming soon. Follow our [Twitter](twitter.com/supabase) to get notified immediately. +Blog post coming soon. Follow our [Twitter](https://twitter.com/supabase) to get notified immediately. ## Wednesday 28 July: Storage v2 @@ -67,7 +67,7 @@ We shipped [Version 1 of Supabase Storage](https://supabase.io/blog/2021/03/30/s ### Where? -Blog post coming soon. Follow our [Twitter](twitter.com/supabase) to get notified immediately. +Blog post coming soon. Follow our [Twitter](https://twitter.com/supabase) to get notified immediately. ## Thursday 29 July: Dashboard v2 @@ -83,7 +83,7 @@ Who needs a futuristic [Hoverboard from 2015](https://www.youtube.com/watch?v=NR ### Where? -Blog post coming soon. Follow our [Twitter](twitter.com/supabase) to get notified immediately. +Blog post coming soon. Follow our [Twitter](https://twitter.com/supabase) to get notified immediately. ## Friday 30 July: One more thing @@ -99,4 +99,4 @@ We all know that the best [SeQueLs](https://www.reddit.com/r/SequelMemes/) are a ### Where? -Blog post coming soon. Follow our [Twitter](twitter.com/supabase) to get notified immediately. \ No newline at end of file +Blog post coming soon. Follow our [Twitter](https://twitter.com/supabase) to get notified immediately. From 1d7608117a003ea6c89d71b2040f0bc9c1eb9be7 Mon Sep 17 00:00:00 2001 From: dshukertjr <18113850+dshukertjr@users.noreply.github.com> Date: Thu, 22 Jul 2021 23:34:42 +0900 Subject: [PATCH 11/17] chore: Added some web specific notes and further refined the guide --- web/docs/guides/with-flutter.mdx | 55 ++++++++++------------- web/static/img/supabase-flutter-demo.png | Bin 0 -> 102880 bytes 2 files changed, 23 insertions(+), 32 deletions(-) create mode 100644 web/static/img/supabase-flutter-demo.png diff --git a/web/docs/guides/with-flutter.mdx b/web/docs/guides/with-flutter.mdx index b111e7a4356..84a2b1e17ba 100644 --- a/web/docs/guides/with-flutter.mdx +++ b/web/docs/guides/with-flutter.mdx @@ -13,34 +13,14 @@ This example provides the steps to build a simple user management app (from scra - Supabase [Database](/docs/guides/database): a Postgres database for storing your user data. - Supabase [Auth](/docs/guides/auth): users can sign in with magic links (no passwords, only email). -- Supabase [Storage](/docs/guides/storage): users can upload a photo. + - [Row Level Security](/docs/guides/auth#row-level-security): data is protected so that individuals can only access their own data. - Instant [APIs](/docs/guides/api): APIs will be automatically generated when you create your database tables. By the end of this guide you'll have an app which allows users to login and update some basic profile details: -![Supabase User Management example](/img/user-management-demo.png) +Supabase User Management example - ## Project set up @@ -179,7 +159,7 @@ Then let's install the only additional dependency: [supabase-flutter](https://gi Open the app and copy and paste the following inside `pubspec.yaml` under `dependencies`. ```yaml -supabase_flutter: ^0.0.3 +supabase_flutter: ^0.0.4 ``` Run `flutter pub get` to install the dependencies. @@ -199,7 +179,7 @@ Now that we have the dependencies installed let's setup deep links so users who That is it on Supabase's end and the rest are platform specific settings: -For Android: +For Android, add an intent-filter to enable deep linking: ```xml title="android/app/src/main/AndroidManifest.xml" @@ -223,7 +203,7 @@ For Android: ``` -For iOS: +For iOS add CFBundleURLTypes to enable deep linking: ```xml title="ios/Runner/Info.plist" @@ -248,8 +228,11 @@ For iOS: ``` For web: + There are no additional configurations. +### main function + Now that we have deep links ready let's initialize the Supabase client inside our `main` function with the API credentials that you copied [earlier](#get-the-api-keys). These variables will be exposed on the app, and that's completely fine since we have [Row Level Security](/docs/guides/auth#row-level-security) enabled on our Database. @@ -298,7 +281,7 @@ class AuthState extends SupabaseAuthState { } ``` -Let's also create a constant file to to make our lives easier. +Let's also create a constant file to make it easier to use Supabase client. ```dart title="lib/utils/constants.dart" import 'package:supabase_flutter/supabase_flutter.dart'; @@ -342,10 +325,11 @@ class _SplashPageState extends AuthState { Let's create a Flutter widget to manage logins and sign ups. We'll use Magic Links, so users can sign in with their email without using passwords. +This page will also inherit `AuthState` as it will handle user login. ```dart title="lib/pages/login_page.dart" +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:supabase_flutter/supabase_flutter.dart'; import 'package:supabase_flutter_guide/components/auth_state.dart'; import 'package:supabase/supabase.dart'; import 'package:supabase_flutter_guide/utils/constants.dart'; @@ -368,7 +352,9 @@ class _LoginPageState extends AuthState { final response = await supabase.auth.signIn( email: _emailController.text, options: AuthOptions( - redirectTo: 'io.supabase.flutterquickstart://login-callback/')); + redirectTo: kIsWeb + ? null + : 'io.supabase.flutterquickstart://login-callback/')); if (response.error != null) { ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: Text(response.error!.message), @@ -424,12 +410,11 @@ class _LoginPageState extends AuthState { ### Set up Account page After a user is signed in we can allow them to edit their profile details and manage their account. - Let's create a new component for that called `account_page.dart`. +Note that this page will also inherit `AuthState` as it will handle user sign out. ```dart title="lib/pages/account_page.dart" import 'package:flutter/material.dart'; -import 'package:supabase_flutter/supabase_flutter.dart'; import 'package:supabase_flutter_guide/components/auth_state.dart'; import 'package:supabase_flutter_guide/utils/constants.dart'; @@ -599,16 +584,22 @@ class MyApp extends StatelessWidget { } ``` -Once that's done, run this in a terminal window: +Once that's done, run this in a terminal window to launch on Android or iOS: ```bash flutter run ``` +Or for web, run the following command to launch it on `localhost:3000` + +```bash +flutter run -d web-server --web-hostname localhost --web-port 3000 +``` + And then open the browser to [localhost:3000](http://localhost:3000) and you should see the completed app. -![Supabase User demo](/img/supabase-react-demo.png) +Supabase User Management example ## Next steps diff --git a/web/static/img/supabase-flutter-demo.png b/web/static/img/supabase-flutter-demo.png new file mode 100644 index 0000000000000000000000000000000000000000..11653b261b8c5be77ea090645bb96d8a0ae28ce2 GIT binary patch literal 102880 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 literal 0 HcmV?d00001 From 3907e686811c47c67e58b7eea9fb7870d330a997 Mon Sep 17 00:00:00 2001 From: dshukertjr <18113850+dshukertjr@users.noreply.github.com> Date: Thu, 22 Jul 2021 23:39:19 +0900 Subject: [PATCH 12/17] chore: Added flutter guide to side bar --- web/sidebars.js | 1 + 1 file changed, 1 insertion(+) diff --git a/web/sidebars.js b/web/sidebars.js index 3e4c4533af6..7b387d05ece 100755 --- a/web/sidebars.js +++ b/web/sidebars.js @@ -89,6 +89,7 @@ module.exports = { 'guides/with-svelte', 'guides/with-vue-3', 'guides/with-angular', + 'guides/with-flutter', 'guides/self-hosting', ], }, From 191e2fc28b6fbb5ea535f0ca2c3b8ec8b3de902b Mon Sep 17 00:00:00 2001 From: ablesoftwaredev <48694187+ablesoftwaredev@users.noreply.github.com> Date: Fri, 23 Jul 2021 00:12:04 +0200 Subject: [PATCH 13/17] Refactor comments in Dart code samples I noticed that the following comment appeared above code where intent was not to sign in user with email and password. // Sign in user with email and password This proposal adds relevant comments, to make code intent clearer. --- web/docs/guides/client-libraries.mdx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/web/docs/guides/client-libraries.mdx b/web/docs/guides/client-libraries.mdx index 3daeea8ba50..8bbbf6e4488 100755 --- a/web/docs/guides/client-libraries.mdx +++ b/web/docs/guides/client-libraries.mdx @@ -116,7 +116,7 @@ import 'package:supabase/supabase.dart'; void main() async { final client = SupabaseClient('supabaseUrl', 'supabaseKey'); - // Sign up user with email and password + // Sign in user with email and password final response = await client .auth .signIn(email: 'example@email.com', password: 'example-password'); @@ -170,7 +170,7 @@ import 'package:supabase/supabase.dart'; void main() async { final client = SupabaseClient('supabaseUrl', 'supabaseKey'); - // Sign up user with email and password + // Sign in user with email and magic link final response = await client .auth .signIn(email: 'example@email.com'); @@ -270,7 +270,7 @@ import 'package:supabase/supabase.dart'; void main() async { final client = SupabaseClient('supabaseUrl', 'supabaseKey'); - // Sign up user with email and password + // Query tables and fetch related data in one round-trip, using select() final response = await client .from('countries') .select('name') @@ -320,7 +320,7 @@ import 'package:supabase/supabase.dart'; void main() async { final client = SupabaseClient('supabaseUrl', 'supabaseKey'); - // Sign up user with email and password + // When fetching data, use advanced filtering to only extract data, that you need. final response = await client .from('cities') .select('name,country_id') @@ -374,7 +374,7 @@ import 'package:supabase/supabase.dart'; void main() async { final client = SupabaseClient('supabaseUrl', 'supabaseKey'); - // Sign up user with email and password + // Create data easily, using insert() final response = await client .from('cities') .insert([ @@ -430,7 +430,7 @@ import 'package:supabase/supabase.dart'; void main() async { final client = SupabaseClient('supabaseUrl', 'supabaseKey'); - // Sign up user with email and password + // Listen to realtime database changes, using subscribe() final response = await client .from('countries') .on(SupabaseEventTypes.all, (payload) { @@ -483,7 +483,7 @@ import 'package:supabase/supabase.dart'; void main() async { final client = SupabaseClient('supabaseUrl', 'supabaseKey'); - // Sign up user with email and password + // You can even listen to Row Level changes final response = await client .from('countries:id.eq.200') .on(SupabaseEventTypes.update, (payload) { From 8fd67699f3c26686a2102427efaa8c726402cb4b Mon Sep 17 00:00:00 2001 From: dshukertjr <18113850+dshukertjr@users.noreply.github.com> Date: Fri, 23 Jul 2021 09:45:47 +0900 Subject: [PATCH 14/17] fix: Fixed typos --- web/docs/guides/with-flutter.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/docs/guides/with-flutter.mdx b/web/docs/guides/with-flutter.mdx index 84a2b1e17ba..44443f37191 100644 --- a/web/docs/guides/with-flutter.mdx +++ b/web/docs/guides/with-flutter.mdx @@ -231,7 +231,7 @@ For web: There are no additional configurations. -### main function +### Main function Now that we have deep links ready let's initialize the Supabase client inside our `main` function with the API credentials that you copied [earlier](#get-the-api-keys). These variables will be exposed on the app, and that's completely fine since we have @@ -289,10 +289,10 @@ import 'package:supabase_flutter/supabase_flutter.dart'; final supabase = Supabase.instance.client; ``` -### SEt up Splash Screen +### Set up Splash Screen Let's create a splash screen that will be shown to users right after they open the app. -This splash screen inherits `AuthState` to redirect users to the appropreate pages depending on their authentication state. +This splash screen inherits `AuthState` to redirect users to the appropriate pages depending on their authentication state. ```dart title="lib/pages/splash_page.dart" import 'package:flutter/material.dart'; From 2a73db899b14bff3af6cc700c18053fc53a368b1 Mon Sep 17 00:00:00 2001 From: dshukertjr <18113850+dshukertjr@users.noreply.github.com> Date: Fri, 23 Jul 2021 09:48:12 +0900 Subject: [PATCH 15/17] chore: Added link to the sample project repo --- web/docs/guides/with-flutter.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/docs/guides/with-flutter.mdx b/web/docs/guides/with-flutter.mdx index 44443f37191..b1bcf43468d 100644 --- a/web/docs/guides/with-flutter.mdx +++ b/web/docs/guides/with-flutter.mdx @@ -21,6 +21,8 @@ By the end of this guide you'll have an app which allows users to login and upda Supabase User Management example +### Github +Whenever you get stuck at any point, take a look at [this repo](https://github.com/dshukertjr/flutter_supabase_quickstart). ## Project set up From f3e99abba40b820fac62ab08bab7789b5e0519fb Mon Sep 17 00:00:00 2001 From: dshukertjr <18113850+dshukertjr@users.noreply.github.com> Date: Fri, 23 Jul 2021 14:27:54 +0900 Subject: [PATCH 16/17] feat: Added example for how to use row level security to implement TTL --- web/docs/guides/auth.mdx | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/web/docs/guides/auth.mdx b/web/docs/guides/auth.mdx index 5e488a89fe4..8fd47316bd9 100644 --- a/web/docs/guides/auth.mdx +++ b/web/docs/guides/auth.mdx @@ -248,6 +248,31 @@ create policy "Only Blizzard staff can update leaderboard" ); ``` +### Time to live for rows + +Policies can also be used to implement TTL or time to live feature that you see in Instagram stories or Snapchat. +In the following example, rows of `stories` table are available only if they have been created within the last 24 hours. + +```sql +-- 1. Create table +create table if not exists stories ( + id uuid not null primary key DEFAULT uuid_generate_v4(), + created_at timestamp with time zone default timezone('utc' :: text, now()) not null, + content text not null +); + +-- 2. Enable RLS +alter table stories + enable row level security; + +-- 3. Create Policy +create policy "Stories are live for a day" + on stories + for select using ( + created_at > (current_timestamp - interval '1 day') + ); +``` + ### Advanced policies Use the full power of SQL to build extremely advanced rules. From 1b094396f9e6d3862016f6ecd7576ba44130f814 Mon Sep 17 00:00:00 2001 From: Paul Copplestone Date: Fri, 23 Jul 2021 18:33:21 +0800 Subject: [PATCH 17/17] minor touchups to the website in the leadup to Launch week - some things we've already shipped :) --- www/components/CaseStudies/index.tsx | 2 +- www/components/ExampleCard.tsx | 9 ++++ www/components/Nav/Developers.tsx | 2 +- www/components/Nav/index.tsx | 25 +++++----- www/data/Announcements.json | 22 +++++++-- www/data/DeveloperFeatures.json | 8 ++-- www/data/tweets/Tweets.json | 72 ++++++++++++++-------------- www/pages/auth/Auth.tsx | 24 ++++------ www/pages/database/Database.tsx | 6 ++- www/pages/storage/Storage.tsx | 32 +++++++++---- 10 files changed, 120 insertions(+), 82 deletions(-) diff --git a/www/components/CaseStudies/index.tsx b/www/components/CaseStudies/index.tsx index 191db508e53..078192c5074 100644 --- a/www/components/CaseStudies/index.tsx +++ b/www/components/CaseStudies/index.tsx @@ -41,7 +41,7 @@ const CaseStudies = () => { ))} - + {/* */} ) } diff --git a/www/components/ExampleCard.tsx b/www/components/ExampleCard.tsx index da2286f3299..b937d6c678b 100644 --- a/www/components/ExampleCard.tsx +++ b/www/components/ExampleCard.tsx @@ -72,6 +72,15 @@ function ExampleCard(props: any) { )} + {!props.demo_url && ( + + + + + + )} diff --git a/www/components/Nav/Developers.tsx b/www/components/Nav/Developers.tsx index 1a48ee169cf..89c88745fa3 100644 --- a/www/components/Nav/Developers.tsx +++ b/www/components/Nav/Developers.tsx @@ -66,7 +66,7 @@ const Developers = () => {
Latest announcements -
    +
      {AnnouncementsData.map((caseStudy: any, idx: number) => (
    • {
- {/*
*/} @@ -330,6 +326,13 @@ const Nav = (props: Props) => { > Pricing + + GitHub +

Products available:

diff --git a/www/data/Announcements.json b/www/data/Announcements.json index d89a6d8d68b..4145701af75 100644 --- a/www/data/Announcements.json +++ b/www/data/Announcements.json @@ -1,12 +1,28 @@ [ { "type": "Announcement", - "title": "Beta launch", - "description": "We're excited to announce we have moved from Alpha to Beta", + "title": "Launch Week II: The SQL", + "description": "We're launching a product every day for one week in July.", "imgUrl": "images/case-study-monitoro.jpg", "logoUrl": "images/logos/monitoro.png", "organization": "Monitoro", - "url": "/beta", + "url": "/blog/2021/07/22/supabase-launch-week-sql", + "postMeta": { + "name": "Paul Copplestone", + "avatarUrl": "https://avatars0.githubusercontent.com/u/10214025?v=4", + "publishDate": "Mar 16, 2020", + "readLength": 6 + }, + "ctaText": "View case study" + }, + { + "type": "Announcement", + "title": "Supabase Storage", + "description": "Supabase launches Storage leveraging Postgres.", + "imgUrl": "images/case-study-monitoro.jpg", + "logoUrl": "images/logos/monitoro.png", + "organization": "Monitoro", + "url": "/blog/2021/03/30/supabase-storage", "postMeta": { "name": "Paul Copplestone", "avatarUrl": "https://avatars0.githubusercontent.com/u/10214025?v=4", diff --git a/www/data/DeveloperFeatures.json b/www/data/DeveloperFeatures.json index c04d5e06ad7..0f6c00fe224 100644 --- a/www/data/DeveloperFeatures.json +++ b/www/data/DeveloperFeatures.json @@ -14,13 +14,13 @@ { "name": "Local emulator", "description": "Develop locally and push to production when you're ready", - "badge": "Q1 2021", - "url": "https://supabasesubscribe.vercel.app/subscription/localEmulator" + "badge": "", + "url": "https://supabase.io/docs/guides/self-hosting" }, { "name": "Supabase CLI", "description": "Manage Supabase projects from your local machine", - "badge": "Q2 2021", - "url": "https://supabasesubscribe.vercel.app/subscription/commandLine" + "badge": "", + "url": "https://github.com/supabase/cli" } ] diff --git a/www/data/tweets/Tweets.json b/www/data/tweets/Tweets.json index 1f0482436e0..a0da5737f65 100644 --- a/www/data/tweets/Tweets.json +++ b/www/data/tweets/Tweets.json @@ -1,21 +1,9 @@ [ { - "text": "Been playing with @supabase_io and so far I'm liking it. I ❤️ you get full access to the database. It's very quick to get up and running, seems a nice fit for prototypes or smaller apps", - "url": "https://twitter.com/mattegreer/status/1341765395133415425", - "handle": "mattegreer", - "img_url": "/images/twitter-profiles/IgXniSVk_400x400.jpg" - }, - { - "text": "Reply enjoying building on @supabase_io for a project with @lasnindrek - allows incredible development speed when bashing together an MVP", - "url": "https://twitter.com/geordidearns/status/1344433863804788737", - "handle": "geordidearns", - "img_url": "/images/twitter-profiles/vppimY3M_400x400.jpg" - }, - { - "text": "OKAY OKAY FINE I'LL LOOK AT SUPABASE PROPERLY", - "url": "https://twitter.com/benbarbersmith/status/1369758528764776453", - "handle": "benbarbersmith", - "img_url": "/images/twitter-profiles/Jqle_tE6_400x400.jpg" + "text": "DB/Backend: @supabase_io Reason: Takes care of Auth, DB hosting, API. Open source, easy to eject into something else. I love SQL. Cloud IDE is incredible for productivity.", + "url": "https://twitter.com/JessetheSibley/status/1369678185508593673", + "handle": "JessetheSibley", + "img_url": "/images/twitter-profiles/aNx9O0lH_400x400.jpg" }, { "text": "Been trying out this new stack. Loving it so far. Next.js (Frontend) + Stitches.js (Styling) + Radix (Primitives & Icons) + Supabase (Backend) + Vercel (Deployment) 😍 Thank you @vercel @Modulz @supabase_io for this amazing DX.", @@ -24,16 +12,28 @@ "img_url": "/images/twitter-profiles/mZAIoZM1_400x400.jpg" }, { - "text": "DB/Backend: @supabase_io Reason: Takes care of Auth, DB hosting, API. Open source, easy to eject into something else. I love SQL. Cloud IDE is incredible for productivity.", - "url": "https://twitter.com/JessetheSibley/status/1369678185508593673", - "handle": "JessetheSibley", - "img_url": "/images/twitter-profiles/aNx9O0lH_400x400.jpg" + "text": "OKAY OKAY FINE I'LL LOOK AT SUPABASE PROPERLY", + "url": "https://twitter.com/benbarbersmith/status/1369758528764776453", + "handle": "benbarbersmith", + "img_url": "/images/twitter-profiles/Jqle_tE6_400x400.jpg" }, { - "text": "Looking for a Firebase alternative? Consider using the open-source @supabase_io. It's as simple as Firebase but I found the dashboard UX more intuitive and hey it's OSS! It's in beta so you can use it for free rn.", - "url": "https://twitter.com/mneelansh15/status/1368171468153118721", - "handle": "mneelansh15", - "img_url": "/images/twitter-profiles/6XKH3Rm6_400x400.jpg" + "text": "@supabase_io is amazing, super easy to get up and running quickly + they have multiple examples with various frameworks (chat app, auth, etc)", + "url": "https://twitter.com/ssw1ss/status/1366515168260337671", + "handle": "ssw1ss", + "img_url": "/images/twitter-profiles/4mD0C5Wk_400x400.jpg" + }, + { + "text": "Been playing with @supabase_io and so far I'm liking it. I ❤️ you get full access to the database. It's very quick to get up and running, seems a nice fit for prototypes or smaller apps", + "url": "https://twitter.com/mattegreer/status/1341765395133415425", + "handle": "mattegreer", + "img_url": "/images/twitter-profiles/IgXniSVk_400x400.jpg" + }, + { + "text": "Using @supabase_io with SWR by @vercel is something else 🔥", + "url": "https://twitter.com/eunjae_lee/status/1369788285317419009", + "handle": "eunjae_lee", + "img_url": "/images/twitter-profiles/eGjSYbQd_400x400.jpg" }, { "text": "big props to the @supabase_io team - open source is a two way street and they’re super responsive & community oriented", @@ -41,6 +41,12 @@ "handle": "_mateomorris", "img_url": "/images/twitter-profiles/1FyEWRE8_400x400.jpg" }, + { + "text": "Enjoying building on @supabase_io for a project with @lasnindrek - allows incredible development speed when bashing together an MVP", + "url": "https://twitter.com/geordidearns/status/1344433863804788737", + "handle": "geordidearns", + "img_url": "/images/twitter-profiles/vppimY3M_400x400.jpg" + }, { "text": "Been actively working on Quill. It's been rapid, thanks to @supabase_io and @tailwindui", "url": "https://twitter.com/quill_web/status/1369061125157961734", @@ -53,12 +59,6 @@ "handle": "MartinOrszulik", "img_url": "/images/twitter-profiles/ext7ggBo_400x400.jpg" }, - { - "text": "Using @supabase_io with SWR by @vercel is something else Fire", - "url": "https://twitter.com/eunjae_lee/status/1369788285317419009", - "handle": "eunjae_lee", - "img_url": "/images/twitter-profiles/eGjSYbQd_400x400.jpg" - }, { "text": "Another month, another impressive @supabase_io release. It’s rare to see a startup ship in public so consistently.", "url": "https://twitter.com/yuris/status/1366770633401491456", @@ -71,12 +71,6 @@ "handle": "swyx", "img_url": "/images/twitter-profiles/qhvO9V6x_400x400.jpg" }, - { - "text": "@supabase_io is amazing, super easy to get up and running quickly + they have multiple examples with various frameworks (chat app, auth, etc)", - "url": "https://twitter.com/ssw1ss/status/1366515168260337671", - "handle": "ssw1ss", - "img_url": "/images/twitter-profiles/4mD0C5Wk_400x400.jpg" - }, { "text": "This weekend I made a personal record 🥇 on the less time spent creating an application with social login / permissions, database, cdn, infinite scaling, git push to deploy and for free. Thanks to @supabase_io and @vercel", "url": "https://twitter.com/jperelli/status/1366195769657720834", @@ -107,6 +101,12 @@ "handle": "prakis", "img_url": "/images/twitter-profiles/eRvqp-t0_400x400.jpg" }, + { + "text": "Looking for a Firebase alternative? Consider using the open-source @supabase_io. It's as simple as Firebase but I found the dashboard UX more intuitive and hey it's OSS! It's in beta so you can use it for free rn.", + "url": "https://twitter.com/mneelansh15/status/1368171468153118721", + "handle": "mneelansh15", + "img_url": "/images/twitter-profiles/6XKH3Rm6_400x400.jpg" + }, { "text": "Me using @supabase_io for the first time right now 🤯", "url": "https://twitter.com/nasiscoe/status/1365140856035024902", diff --git a/www/pages/auth/Auth.tsx b/www/pages/auth/Auth.tsx index 5302f45f424..f3c846e2195 100644 --- a/www/pages/auth/Auth.tsx +++ b/www/pages/auth/Auth.tsx @@ -118,20 +118,15 @@ function AuthPage() {
+

All the social providers -

- Enable social logins with the click of a button. Google, Facebook, Github, Azure, - Gitlab and Bitbucket. +

+ Enable social logins with the click of a button. Google, Facebook, GitHub, Azure, + Gitlab, Twitter, Discord, and Bitbucket.

- - -

- Twitter coming soon -

-
@@ -142,10 +137,10 @@ function AuthPage() { Fully integrated -

- Incredibly simple Auth, without a single external authentication service. +

+ Incredibly simple Auth, without a single external authentication service. Built-in + Authentication, Authorization, and User Management.

-

Built-in Authentication, Authorization, and User Management.

@@ -156,11 +151,10 @@ function AuthPage() { Own your data -

+

User data stored in your Supabase database so you never have to worry about 3rd - party privacy issues. + party privacy issues. Host your data in 8 different locations.

-

Host your data in 8 different regions.

diff --git a/www/pages/database/Database.tsx b/www/pages/database/Database.tsx index aa9482b40b2..df51e42e25d 100644 --- a/www/pages/database/Database.tsx +++ b/www/pages/database/Database.tsx @@ -155,7 +155,11 @@ function Database() {

- + + + + +

Realtime enabled diff --git a/www/pages/storage/Storage.tsx b/www/pages/storage/Storage.tsx index 20289f61add..2e027bd8b14 100644 --- a/www/pages/storage/Storage.tsx +++ b/www/pages/storage/Storage.tsx @@ -35,7 +35,7 @@ function StoragePage() { const meta_title = 'Storage | Store any digital content' const meta_description = - 'An open source Object store service with unlimited scalability, for any file type.' + 'An open source Object store with unlimited scalability, for any file type.' return ( <> @@ -64,7 +64,7 @@ function StoragePage() { , ]} subheader={[ - 'An open source Object store service with unlimited scalability, for any file type.', + 'An open source Object store with unlimited scalability, for any file type.', 'With custom policies and permissions that are familiar and easy to implement.', ]} image={[ @@ -116,8 +116,14 @@ function StoragePage() {
-

- +

+ + +

Lightning fast @@ -133,8 +139,14 @@ function StoragePage() {
-

- +

+ + +

Dependable @@ -201,11 +213,11 @@ function StoragePage() {

, ]} footer={[ -
+
} - title="CDN integration" + title="CDN" text="Serve from the edge to reduce latency." /> Coming soon @@ -213,7 +225,7 @@ function StoragePage() {
} - title="Auto transformation & optimization" + title="Transformations" text="Resize and compress your media before you serve it." /> Coming soon @@ -243,7 +255,7 @@ function StoragePage() { with Supabase Auth -

+

Using Postgres Row Level Security to create Object access rules.