Supabase和Svelte快速入门指南

736 阅读5分钟

Supabase和Svelte快速入门指南

这个例子提供了使用Supabase和Svelte建立一个简单的用户管理应用的步骤(从头开始!)。

这个例子提供了使用Supabase和Svelte建立一个简单的用户管理应用(从头开始!)的步骤:

  • Supabase数据库:一个用于存储使用数据的Postgres数据库。
  • Supabase Auth:用户可以用魔法链接登录(没有密码,只有电子邮件)。
  • Supabase存储:用户可以上传照片。
  • 行级安全:数据受到保护,个人只能访问自己的数据。
  • 即时API。当你创建你的数据库表时,API将自动生成。

在本指南结束时,你将拥有一个允许用户登录并更新一些基本的个人资料细节的应用程序。

GitHub

每当你在任何时候被卡住,就看看这个 repo

项目设置

在我们开始构建之前,我们要设置我们的数据库和API。这很简单,就是在Supabase中启动一个新的项目,然后在数据库中创建一个 "模式"。

创建一个项目

进入app.supabase.com

  1. 点击 "新项目"。
  2. 输入你的项目细节。
  3. 等待新数据库的启动。

设置数据库模式

现在我们要设置数据库模式。我们可以使用SQL编辑器中的 "User Management Starter "快速入门,或者你可以直接复制/粘贴下面的SQL并自己运行。

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' );

UI

  1. 转到 "SQL "部分。
  2. 点击 "User Management Starter"。
  3. 点击 "运行"。

获取API密钥

现在你已经创建了一些数据库表,你已经准备好使用自动生成的API插入数据。我们只需要从API设置中获得URL和anon key。

  1. 转到 "SQL "部分。
  2. 点击 "用户管理启动器"。
  3. 点击 "运行"。

构建应用程序

让我们开始从头开始构建Svelte应用程序。

初始化一个Svelte应用程序

我们可以使用Quickstart Svelte模板来初始化一个名为supabase-svelte 的应用程序。

外壳

npx degit sveltejs/template supabase-svelte
cd supabase-svelte

然后让我们安装唯一的额外依赖:supabase-js

npm

npm install @supabase/supabase-js

Yarn

yarn add @supabase/supabase-js

最后,我们要把环境变量保存在.env 。我们只需要API URL和你之前复制的anon key。

壳牌

env

SVELTE_APP_SUPABASE_URL=YOUR_SUPABASE_URL
SVELTE_APP_SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY

我们的应用程序几乎可以正常工作了,为了使svelte能够与supabase和.env文件一起工作,我们首先需要对rollup.config.js 文件做一些修改。Supabase导入了json 文件,为了将.json文件转换为ES6模块,我们需要通过运行@rollup/plugin-json 安装它。

npm

外壳

npm install --save-dev @rollup/plugin-json

Yarn

Shell

yarn add --save-dev dotenv @rollup/plugin-replace

并将这些插件添加到rollup.config.js 文件中。

JavaScript

 rollup.config.js

import { config } from 'dotenv';
  import replace from '@rollup/plugin-replace';
  import json from '@rollup/plugin-json'

  export default {
    plugins: [
    replace({
            __api: JSON.stringify({
                env: {
                    isProd: production,
                    ...config().parsed // attached the .env config
                }
            }),
            delimiters: ['', '']
        }),
        json(),
    // ...
    ],
    // ...
  }

现在我们已经有了API凭证,让我们创建一个辅助文件来初始化Supabase客户端。这些变量将暴露在浏览器上,这完全没有问题,因为我们在数据库上启用了行级安全

JavaScript

src/supabaseClient.js

import { createClient } from '@supabase/supabase-js'

const supabaseUrl = __api.env.SVELTE_APP_SUPABASE_URL
const supabaseAnonKey = __api.env.SVELTE_APP_SUPABASE_ANON_KEY

export const supabase = createClient(supabaseUrl, supabaseAnonKey)

还有一个可选的步骤是更新CSS文件public/global.css ,使应用程序看起来漂亮。你可以在这里找到这个文件的全部内容。

设置一个登录组件

让我们来设置一个Svelte组件来管理登录和注册。我们将使用Magic Links,这样用户就可以用他们的电子邮件登录,而无需使用密码。

HTML

/src/Auth.svelte

<form class="row flex flex-center" on:submit|preventDefault={handleLogin}>
  <div class="col-6 form-widget">
    <h1 class="header">Supabase + Svelte</h1>
    <p class="description">Sign in via magic link with your email below</p>
    <div>
      <input
        class="inputField"
        type="email"
        placeholder="Your email"
        bind:value={email}
      />
    </div>
    <div>
      <input type="submit" class='button block' value={loading ? "Loading" : "Send magic link"} disabled={loading} />
    </div>
  </div>
</form>

用户存储

为了在其他地方访问用户信息,我们使用一个可写存储。创建一个新的文件,名为sessionStore.js

的文件。

src/sessionStore.js

import { writable } from 'svelte/store';

export const user = writable(false);

帐户页面

在用户登录后,我们可以让他们编辑他们的个人资料细节和管理他们的账户。让我们为此创建一个新的组件,名为Profile.svelte

HTML

src/Profile.svelte

<form use:getProfile class="form-widget" on:submit|preventDefault={updateProfile}>
  <div>
    <label for="email">Email</label>
    <input id="email" type="text" value={$user.email} disabled />
  </div>
  <div>
    <label for="username">Name</label>
    <input
      id="username"
      type="text"
      bind:value={username}
    />
  </div>
  <div>
    <label for="website">Website</label>
    <input
      id="website"
      type="website"
      bind:value={website}
    />
  </div>

  <div>
    <input type="submit" class="button block primary" value={loading ? 'Loading ...' : 'Update'} disabled={loading}/>
  </div>

  <div>
    <button class="button block" on:click={signOut} disabled={loading}>
      Sign Out
    </button>
  </div>
</form>

启动!

现在我们已经有了所有的组件,让我们来更新App.svelte

HTML

src/App.svelte

<div class="container" style="padding: 50px 0 100px 0;">
    {#if $user}
        <Profile />
    {:else}
        <Auth />
    {/if}
</div>

一旦完成,在终端窗口中运行这个。

npm

外壳

npm run dev

Yarn

壳牌

yarn dev

然后打开浏览器到localhost:5000,你应该看到完成的应用程序。

⚠️警告:Svelte默认使用port 5000 ,Supabase使用port 3000 。要改变supabase的重定向端口,请进入:Authentication > Settings ,并将Site Url 改为localhost:5000

奖励:个人资料照片

每个Supabase项目都配置了用于管理照片和视频等大文件的存储器

创建一个上传小工具

让我们为用户创建一个头像,以便他们可以上传个人资料照片。我们可以从创建一个新的组件开始。

HTML

src/Avatar.svelte

<div>
  {#if path}
    <img use:downloadImage
      {src}
      alt="Avatar"
      class="avatar image"
      style="height: {size}; width: {size};"
    />
  {:else}
    <div class="avatar no-image" style="height: {size}; width: {size};" />
  {/if}
  
  <div style="width: {size};">
    <label class="button primary block" for="single">
      {uploading ? 'Uploading ...' : 'Upload'}
    </label>
    <input
      style="visibility: hidden; position:absolute;"
      type="file"
      id="single"
      accept="image/*"
      bind:files
      on:change={uploadAvatar}
      disabled={uploading}
    />
  </div>
</div>

添加新的小部件

然后我们可以把小部件添加到账户页面。

HTML

src/Profile.svelte

<form use:getProfile class="form-widget" on:submit|preventDefault={updateProfile}>
  <!-- Add to body -->
  <Avatar bind:path={avatar_url} on:upload={updateProfile} />

  <!-- Other form elements -->
</form>