Table des matières
Création de l'application
Créer une table de données
Créer un bucket d'avatars
Obtenir la clé API
Paramètres d'authentification
Créer l'application
Initialiser le projet
更新样式
设置登录组件
Memfiredb + Angular
用户信息页面
🎜🎜Configurons un composant angulaire pour gérer Connectez-vous et inscrivez-vous. Nous utiliserons Magic Links pour que les utilisateurs puissent se connecter en utilisant leur adresse e-mail sans avoir à utiliser de mot de passe. Créez un 🎜AuthComponent à l'aide des commandes Angular CLI. 🎜 ng g c auth🎜🎜src/app/auth/auth.component.ts🎜rrreee

🎜Page d'informations sur l'utilisateur🎜🎜🎜Une fois l'utilisateur connecté , nous pouvons être autorisés à modifier les détails de leur profil et à gérer leur compte. Créez un 🎜AccountComponent à l'aide des commandes Angular CLI. 🎜 ng g c account🎜🎜src/app/account/account.component.ts🎜rrreee🎜🎜Modifiez le fichier d'entrée du projet🎜🎜🎜Maintenant que tous les composants sont prêts, mettons à jour 🎜AppComponent🎜 :🎜" >🎜Définir le composant de connexion🎜🎜🎜🎜🎜Configurons un composant angulaire pour gérer Connectez-vous et inscrivez-vous. Nous utiliserons Magic Links pour que les utilisateurs puissent se connecter en utilisant leur adresse e-mail sans avoir à utiliser de mot de passe. Créez un 🎜AuthComponent à l'aide des commandes Angular CLI. 🎜 ng g c auth🎜🎜src/app/auth/auth.component.ts🎜rrreee

🎜Page d'informations sur l'utilisateur🎜🎜🎜Une fois l'utilisateur connecté , nous pouvons être autorisés à modifier les détails de leur profil et à gérer leur compte. Créez un 🎜AccountComponent à l'aide des commandes Angular CLI. 🎜 ng g c account🎜🎜src/app/account/account.component.ts🎜rrreee🎜🎜Modifiez le fichier d'entrée du projet🎜🎜🎜Maintenant que tous les composants sont prêts, mettons à jour 🎜AppComponent🎜 :🎜

实现:上传头像及更新用户信息
创建上传小组件
Maison interface Web js tutoriel Parlons de la façon de créer des applications angulaires à l'aide de MemFire ​​​​Cloud

Parlons de la façon de créer des applications angulaires à l'aide de MemFire ​​​​Cloud

Aug 30, 2022 pm 08:44 PM
angular

Comment créer une application Angular ? L'article suivant vous présentera comment utiliser MemFire ​​​​Cloud pour créer des applications angulaires. J'espère qu'il vous sera utile !

Parlons de la façon de créer des applications angulaires à l'aide de MemFire ​​​​Cloud

【Recommandation de didacticiel connexe : "Tutoriel angulaire"】

MemFire ​​​​Cloud est une base de données cloud qui offre aux utilisateurs la possibilité de créer des bases de données cloud, de gérer la base de données et de sauvegarder la base de données. Il fournit également un backend en tant que service. Les utilisateurs peuvent créer une nouvelle application en 1 minute, utiliser des API et des SDK générés automatiquement et accéder aux bases de données cloud, au stockage d'objets, à l'authentification et à l'autorisation des utilisateurs, ainsi qu'à d'autres fonctions. coder et accélérer le développement d’applications WEB ou APP.

Adresse de la vidéo d'apprentissage : www.bilibili.com/video/BV1wt…

Cet exemple fournit les étapes pour créer une application de gestion d'utilisateurs simple (à partir de zéro) en utilisant MemFire ​​​​Cloud et angulaire. Cela inclut :

  • MemFire ​​​​Cloud : base de données MemFireDB pour stocker les données utilisateur.
  • Vérification de l'utilisateur MemFire ​​​​Cloud : les utilisateurs peuvent se connecter en utilisant le lien magique (uniquement l'e-mail requis, aucun mot de passe requis).
  • MemFire ​​​​Cloud Storage : les utilisateurs peuvent télécharger des photos.
  • Politique de sécurité au niveau de la ligne : les données sont protégées afin que les individus ne puissent accéder qu'à leurs propres données.
  • API instantanée : l'API est automatiquement générée lors de la création d'une table de base de données.

À la fin de ce guide, vous disposerez d'une application qui permet aux utilisateurs de se connecter et de mettre à jour certains détails de base de leur profil :

Parlons de la façon de créer des applications angulaires à laide de MemFire ​​​​Cloud

Création de l'application

Objectif : Notre application est créée ici Obtenir une série de ressources tels que les bases de données et le stockage cloud, et obtenez le lien d'accès API exclusif et la clé d'accès de l'application. Les utilisateurs peuvent facilement interagir avec les ressources ci-dessus.

Connexioncloud.memfiredb.com/auth/loginCréer une application

Parlons de la façon de créer des applications angulaires à laide de MemFire ​​​​Cloud

Créer une table de données

Cliquez sur l'application pour créer visuellement la table de données

1 Créer la table des profils ;

Sur les données. page de la table, cliquez sur "Nouvelle table de données", la configuration de la page est la suivante :

Parlons de la façon de créer des applications angulaires à laide de MemFire ​​​​Cloud

où l'identifiant du champ de la table des profils est lié à la clé étrangère du champ id (type uuid) dans la table auth.users.

2. Activez les règles d'accès de sécurité aux données RLS pour les profils ;

Sélectionnez la table Profils créée, cliquez sur la barre d'autorisation de la table, comme indiqué dans la figure ci-dessous, cliquez sur le bouton "Activer RLS"

Parlons de la façon de créer des applications angulaires à laide de MemFire ​​​​Cloud

3. chaque utilisateur pour afficher les informations personnelles publiques ;

Cliquez sur le bouton « Nouvelle règle », dans la boîte de dialogue contextuelle, sélectionnez « Activer l'accès pour tous les utilisateurs », saisissez le nom de la politique, sélectionnez l'opération « SÉLECTIONNER (requête) » et cliquez sur le bouton « Créer une politique », comme indiqué ci-dessous.

Parlons de la façon de créer des applications angulaires à laide de MemFire ​​​​Cloud

4. Autorisez uniquement les utilisateurs à ajouter, supprimer, modifier et vérifier leurs informations de profil personnel ;

Cliquez sur le bouton "Nouvelle règle", dans la boîte contextuelle, sélectionnez "Activer les autorisations d'accès pour les utilisateurs en fonction de l'utilisateur". ID" et entrez le nom de la stratégie. Sélectionnez l'opération "TOUS" et cliquez sur le bouton "Créer une stratégie", comme indiqué ci-dessous.

Parlons de la façon de créer des applications angulaires à laide de MemFire ​​​​Cloud

Créer un bucket d'avatars

Créez un bucket de stockage cloud pour stocker l'image de l'avatar de l'utilisateur. Les opérations impliquées incluent :

1. Créez un bucket d'avatars

Accédez au stockage cloud de la colonne de l'application, cliquez sur. le bouton "Nouveau bucket" pour créer des avatars de bucket.

Parlons de la façon de créer des applications angulaires à laide de MemFire ​​​​Cloud

2. Autorisez chaque utilisateur à afficher les avatars du bucket

Sélectionnez les avatars du bucket, passez à la colonne Paramètres d'autorisation, cliquez sur le bouton "Nouvelle règle", une boîte de dialogue contextuelle d'édition de politique apparaîtra, sélectionnez "Personnalisé", comme le montre l'image ci-dessous :

Parlons de la façon de créer des applications angulaires à laide de MemFire ​​​​Cloud

Sélectionnez l'opération SELECT, entrez le nom de la stratégie et cliquez sur le bouton « Générer une stratégie », comme indiqué dans la figure ci-dessous.

Parlons de la façon de créer des applications angulaires à laide de MemFire ​​​​Cloud

3. Autorisez les utilisateurs à télécharger des avatars de bucket ;

Sélectionnez les avatars de bucket, passez à la colonne Paramètres d'autorisation, cliquez sur le bouton "Nouvelle règle", une boîte de dialogue d'édition de politique apparaîtra, sélectionnez "Personnalisé", comme indiqué ci-dessous Comme indiqué :

Parlons de la façon de créer des applications angulaires à laide de MemFire ​​​​Cloud

Sélectionnez l'opération INSÉRER, entrez le nom de la stratégie et cliquez sur le bouton "Générer une stratégie", comme indiqué dans la figure ci-dessous.

1Parlons de la façon de créer des applications angulaires à laide de MemFire ​​​​Cloud

Afficher les résultats

1Parlons de la façon de créer des applications angulaires à laide de MemFire ​​​​Cloud

Toutes les tables de données et SQL de RLS (le nom de la stratégie est remplacé par l'anglais)

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

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 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' );
Copier après la connexion

Obtenir la clé API

Maintenant que vous avez créé des tables de base de données, vous pouvez utiliser la API générée pour insérer des données. Nous avons juste besoin d'obtenir l'URL et la clé d'anon à partir des paramètres de l'API.

Sur la page Application->Résumé, obtenez l'adresse du service et les informations sur le jeton.

La clé Anon (publique) est la clé API du client. Il permet un « accès anonyme » à votre base de données jusqu'à ce que l'utilisateur se connecte. Après la connexion, la clé est remplacée par le propre jeton de connexion de l'utilisateur. Cela permettra la sécurité au niveau des lignes pour les données.

REMARQUE : La clé service_role (secret) permet un accès complet à vos données, en contournant toute politique de sécurité. Cette clé doit être gardée secrète et utilisée dans un environnement serveur, jamais sur le client ou le navigateur. Dans l’exemple de code suivant, supabaseUrl et supabaseKey doivent être fournis.

Paramètres d'authentification

Lorsque l'utilisateur clique sur le lien magique dans l'e-mail pour se connecter, il doit accéder à l'interface de connexion de notre application. Ici, vous devez configurer la redirection d'URL appropriée dans les paramètres d'authentification.

Parce que notre application finale sera démarrée sur le port local 4200 (ou d'autres ports), nous définissons donc ici temporairement l'url sur http://localhost:4200

De plus, cette interface peut également être personnalisée. Utilisez notre propre smtp serveur.

Créer l'application

Créons une application Angular à partir de zéro.

Initialiser le projet

Nous pouvons utiliser Angular CLI pour initialiser un projet nommé memfiredb-angular : memfiredb-angular

Angular 需要 Node.js (>=14.15

npm install -g @angular/cli
npx ng new memfiredb-angular --routing false --style css
cd memfiredb-angular
Copier après la connexion

然后让我们安装唯一的附加依赖项:supabase-js

npm install @supabase/supabase-js
Copier après la connexion

最后,我们要将环境变量保存在environment.ts, 我们需要的是 API URL 和您上面anon复制的密钥。

src/environments/environment.ts文件

export const environment = {
  production: false,
  supabaseUrl: "YOUR_SUPABASE_URL",
  supabaseKey: "YOUR_SUPABASE_KEY"
};
Copier après la connexion

现在我们已经有了 API 凭证,通过ng g s supabase创建一个SupabaseService来初始化 Supabase 客户端并实现与 Supabase API 通信的函数。

src/app/supabase.service.ts

import { Injectable } from '@angular/core';
import {AuthChangeEvent, createClient, Session, SupabaseClient} from '@supabase/supabase-js';
import {environment} from "../environments/environment";

export interface Profile {
  username: string;
  website: string;
  avatar_url: string;
}

@Injectable({
  providedIn: 'root'
})
export class SupabaseService {
  private supabase: SupabaseClient;

  constructor() {
    this.supabase = createClient(environment.supabaseUrl, environment.supabaseKey);
  }

  get user() {
    return this.supabase.auth.user();
  }

  get session() {
    return this.supabase.auth.session();
  }

  get profile() {
    return this.supabase
      .from('profiles')
      .select(`username, website, avatar_url`)
      .eq('id', this.user?.id)
      .single();
  }

  authChanges(callback: (event: AuthChangeEvent, session: Session | null) => void) {
    return this.supabase.auth.onAuthStateChange(callback);
  }

  signIn(email: string) {
    return this.supabase.auth.signIn({email});
  }

  signOut() {
    return this.supabase.auth.signOut();
  }

  updateProfile(profile: Profile) {
    const update = {
      ...profile,
      id: this.user?.id,
      updated_at: new Date()
    }

    return this.supabase.from('profiles').upsert(update, {
      returning: 'minimal', // Don't return the value after inserting
    });
  }

  downLoadImage(path: string) {
    return this.supabase.storage.from('avatars').download(path);
  }

  uploadAvatar(filePath: string, file: File) {
    return this.supabase.storage
      .from('avatars')
      .upload(filePath, file);
  }
}
Copier après la connexion

更新样式

可以看到界面实在是不怎么优雅,更新下样式,让它好看一些。 修改src/styles.css文件。

html,
body {
  --custom-font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu,
    Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
  --custom-bg-color: #101010;
  --custom-panel-color: #222;
  --custom-box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.8);
  --custom-color: #fff;
  --custom-color-brand: #24b47e;
  --custom-color-secondary: #666;
  --custom-border: 1px solid #333;
  --custom-border-radius: 5px;
  --custom-spacing: 5px;

  padding: 0;
  margin: 0;
  font-family: var(--custom-font-family);
  background-color: var(--custom-bg-color);
}

* {
  color: var(--custom-color);
  font-family: var(--custom-font-family);
  box-sizing: border-box;
}

html,
body,
#__next {
  height: 100vh;
  width: 100vw;
  overflow-x: hidden;
}

/* Grid */

.container {
  width: 90%;
  margin-left: auto;
  margin-right: auto;
}
.row {
  position: relative;
  width: 100%;
}
.row [class^='col'] {
  float: left;
  margin: 0.5rem 2%;
  min-height: 0.125rem;
}
.col-1,
.col-2,
.col-3,
.col-4,
.col-5,
.col-6,
.col-7,
.col-8,
.col-9,
.col-10,
.col-11,
.col-12 {
  width: 96%;
}
.col-1-sm {
  width: 4.33%;
}
.col-2-sm {
  width: 12.66%;
}
.col-3-sm {
  width: 21%;
}
.col-4-sm {
  width: 29.33%;
}
.col-5-sm {
  width: 37.66%;
}
.col-6-sm {
  width: 46%;
}
.col-7-sm {
  width: 54.33%;
}
.col-8-sm {
  width: 62.66%;
}
.col-9-sm {
  width: 71%;
}
.col-10-sm {
  width: 79.33%;
}
.col-11-sm {
  width: 87.66%;
}
.col-12-sm {
  width: 96%;
}
.row::after {
  content: '';
  display: table;
  clear: both;
}
.hidden-sm {
  display: none;
}

@media only screen and (min-width: 33.75em) {
  /* 540px */
  .container {
    width: 80%;
  }
}

@media only screen and (min-width: 45em) {
  /* 720px */
  .col-1 {
    width: 4.33%;
  }
  .col-2 {
    width: 12.66%;
  }
  .col-3 {
    width: 21%;
  }
  .col-4 {
    width: 29.33%;
  }
  .col-5 {
    width: 37.66%;
  }
  .col-6 {
    width: 46%;
  }
  .col-7 {
    width: 54.33%;
  }
  .col-8 {
    width: 62.66%;
  }
  .col-9 {
    width: 71%;
  }
  .col-10 {
    width: 79.33%;
  }
  .col-11 {
    width: 87.66%;
  }
  .col-12 {
    width: 96%;
  }
  .hidden-sm {
    display: block;
  }
}

@media only screen and (min-width: 60em) {
  /* 960px */
  .container {
    width: 75%;
    max-width: 60rem;
  }
}

/* Forms */

label {
  display: block;
  margin: 5px 0;
  color: var(--custom-color-secondary);
  font-size: 0.8rem;
  text-transform: uppercase;
}

input {
  width: 100%;
  border-radius: 5px;
  border: var(--custom-border);
  padding: 8px;
  font-size: 0.9rem;
  background-color: var(--custom-bg-color);
  color: var(--custom-color);
}

input[disabled] {
  color: var(--custom-color-secondary);
}

/* Utils */

.block {
  display: block;
  width: 100%;
}
.inline-block {
  display: inline-block;
  width: 100%;
}
.flex {
  display: flex;
}
.flex.column {
  flex-direction: column;
}
.flex.row {
  flex-direction: row;
}
.flex.flex-1 {
  flex: 1 1 0;
}
.flex-end {
  justify-content: flex-end;
}
.flex-center {
  justify-content: center;
}
.items-center {
  align-items: center;
}
.text-sm {
  font-size: 0.8rem;
  font-weight: 300;
}
.text-right {
  text-align: right;
}
.font-light {
  font-weight: 300;
}
.opacity-half {
  opacity: 50%;
}

/* Button */

button,
.button {
  color: var(--custom-color);
  border: var(--custom-border);
  background-color: var(--custom-bg-color);
  display: inline-block;
  text-align: center;
  border-radius: var(--custom-border-radius);
  padding: 0.5rem 1rem;
  cursor: pointer;
  text-align: center;
  font-size: 0.9rem;
  text-transform: uppercase;
}

button.primary,
.button.primary {
  background-color: var(--custom-color-brand);
  border: 1px solid var(--custom-color-brand);
}

/* Widgets */

.card {
  width: 100%;
  display: block;
  border: var(--custom-border);
  border-radius: var(--custom-border-radius);
  padding: var(--custom-spacing);
}

.avatar {
  border-radius: var(--custom-border-radius);
  overflow: hidden;
  max-width: 100%;
}
.avatar.image {
  object-fit: cover;
}
.avatar.no-image {
  background-color: #333;
  border: 1px solid rgb(200, 200, 200);
  border-radius: 5px;
}

.footer {
  position: absolute;
  max-width: 100%;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  flex-flow: row;
  border-top: var(--custom-border);
  background-color: var(--custom-bg-color);
}
.footer div {
  padding: var(--custom-spacing);
  display: flex;
  align-items: center;
  width: 100%;
}
.footer div > img {
  height: 20px;
  margin-left: 10px;
}
.footer > div:first-child {
  display: none;
}
.footer > div:nth-child(2) {
  justify-content: left;
}

@media only screen and (min-width: 60em) {
  /* 960px */
  .footer > div:first-child {
    display: flex;
  }
  .footer > div:nth-child(2) {
    justify-content: center;
  }
}

@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.mainHeader {
  width: 100%;
  font-size: 1.3rem;
  margin-bottom: 20px;
}

.avatarPlaceholder {
  border: var(--custom-border);
  border-radius: var(--custom-border-radius);
  width: 35px;
  height: 35px;
  background-color: rgba(255, 255, 255, 0.2);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Auth */

.auth-widget {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.auth-widget > .button {
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background-color: #444444;
  text-transform: none !important;
  transition: all 0.2s ease;
}

.auth-widget .button:hover {
  background-color: #2a2a2a;
}

.auth-widget .button > .loader {
  width: 17px;
  animation: spin 1s linear infinite;
  filter: invert(1);
}

/* Account */

.account {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.account > * > .avatarField {
  display: flex;
  align-items: center;
  margin-bottom: 30px;
}

.account > * > .avatarField > .avatarContainer {
  margin-right: 20px;
}

/* Profile Card */

.profileCard {
  border-radius: 5px;
  display: flex;
  border: var(--custom-border);
  background-color: var(--custom-panel-color);
  padding: 20px 20px;
  margin-bottom: 20px;
}

.profileCard:last-child {
  margin-bottom: 0px;
}

.profileCard > .userInfo {
  margin-left: 20px;
  font-weight: 300;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.profileCard > .userInfo > p {
  margin: 0;
}

.profileCard > .userInfo > .username {
  font-size: 1.3rem;
  font-weight: 500;
  margin-bottom: 5px;
}

.profileCard > .userInfo > .website {
  font-size: 0.9rem;
  color: var(--custom-color-brand);
  margin-bottom: 10px;
  text-decoration: none;
}
Copier après la connexion

设置登录组件

让我们设置一个 Angular 组件来管理登录和注册。我们将使用 Magic Links,因此用户无需使用密码即可使用电子邮件登录。使用Angular CLI 命令创建一个AuthComponent 。 ng g c auth

src/app/auth/auth.component.ts

import { Component } from '@angular/core';
import {SupabaseService} from "../supabase.service";

@Component({
  selector: 'app-auth',
  template: `
    <div>
      <form>
        <h1 id="Memfiredb-Angular">Memfiredb + Angular</h1>
        <p>使用下面的电子邮件通过魔术链接登录</p>
        <div>
          <input>
        </div>
        <div>
          <button>
          {{loading ? 'Loading' : 'Send magic link'}}
          </button>
        </div>
      </form>
    </div>
  `,
})
export class AuthComponent {
  loading = false;

  constructor(private readonly supabase: SupabaseService) { }

  async handleLogin(input: string) {
    try {
      this.loading = true;
      await this.supabase.signIn(input);
      alert('请检查您的电子邮件以获取登录链接!');
    } catch (error:any) {
      alert(error.error_description || error.message)
    } finally {
      this.loading = false;
    }
  }
}
Copier après la connexion

用户信息页面

用户登录后,我们可以允许他们编辑他们的个人资料详细信息并管理他们的帐户。使用Angular CLI 命令创建一个AccountComponent 。 ng g c account

Angular nécessite Node.js (>=14.15
import {Component, Input, OnInit} from '@angular/core';
import {Profile, SupabaseService} from "../supabase.service";
import {Session} from "@supabase/supabase-js";

@Component({
  selector: 'app-account',
  template: `
    <div>
      <div>
        <label>邮箱</label>
        <input>
      </div>
      <div>
        <label>名称</label>
        <input>
      </div>
      <div>
        <label>网址</label>
        <input>
      </div>

      <div>
        <button>
          {{loading ? 'Loading ...' : 'Update'}}
        </button>
      </div>

      <div>
        <button>
          退出登录
        </button>
      </div>
    </div>
  `
})
export class AccountComponent implements OnInit {
  loading = false;
  profile: Profile | undefined;

  @Input() session: Session | undefined;

  constructor(private readonly supabase: SupabaseService) { }

  ngOnInit() {
    this.getProfile();
  }

  async getProfile() {
    try {
      this.loading = true;
      let {data: profile, error, status} = await this.supabase.profile;

      if (error && status !== 406) {
        throw error;
      }

      if (profile) {
        this.profile = profile;
      }
    } catch (error:any) {
      alert(error.message)
    } finally {
      this.loading = false;
    }
  }

  async updateProfile(username: string, website: string, avatar_url: string = '') {
    try {
      this.loading = true;
      await this.supabase.updateProfile({username, website, avatar_url});
    } catch (error:any) {
      alert(error.message);
    } finally {
      this.loading = false;
    }
  }

  async signOut() {
    await this.supabase.signOut();
  }
}
Copier après la connexion
Ensuite, installons la seule dépendance supplémentaire : supabase-js

import {Component, OnInit} from '@angular/core';
import {SupabaseService} from "./supabase.service";

@Component({
  selector: 'app-root',
  template: `
  <div>
    <app-account></app-account>
    <ng-template>
      <app-auth></app-auth>
    </ng-template>
  </div>
  `
})
export class AppComponent implements OnInit {
  session = this.supabase.session;

  constructor(private readonly supabase: SupabaseService) { }

  ngOnInit() {
    this.supabase.authChanges((_, session) => this.session = session);
  }
}
Copier après la connexion
Copier après la connexion
Enfin, nous devons enregistrer les variables d'environnement dans Environment.ts. Ce dont nous avons besoin, c'est de l'URL de l'API et de la clé que vous avez copiée ci-dessus anon.

fichier src/environments/environment.ts

npm run start
Copier après la connexion
Copier après la connexion
Maintenant que nous avons les informations d'identification de l'API, créez un

SupabaseService🎜 via ng g s supabase pour initialiser le client Supabase et implémenter des fonctions pour communiquer avec la Supabase API. 🎜🎜src/app/supabase.service.ts🎜
import {Component, EventEmitter, Input, Output} from '@angular/core';
import {SupabaseService} from "../supabase.service";
import {DomSanitizer, SafeResourceUrl} from "@angular/platform-browser";

@Component({
  selector: 'app-avatar',
  template: `
    <div>
      <img  alt="Parlons de la façon de créer des applications angulaires à l'aide de MemFire ​​​​Cloud" >
</div>
    <div></div>
    <div>
      <label>
        {{uploading ? 'Uploading ...' : 'Upload'}}
      </label>
      <input>
    </div>
  `,
})
export class AvatarComponent {
  _avatarUrl: SafeResourceUrl | undefined;
  uploading = false;

  @Input()
  set avatarUrl(url: string | undefined) {
    if (url) {
      this.downloadImage(url);
    }
  };

  @Output() upload = new EventEmitter<string>();

  constructor(
    private readonly supabase: SupabaseService,
    private readonly dom: DomSanitizer
  ) { }

  async downloadImage(path: string) {
    try {
      const {data} = await this.supabase.downLoadImage(path);
       if (data instanceof Blob) {
        this._avatarUrl = this.dom.bypassSecurityTrustResourceUrl(
          URL.createObjectURL(data)
        );
      }
    } catch (error:any) {
      console.error('下载图片出错: ', error.message);
    }
  }

  async uploadAvatar(event: any) {
    try {
      this.uploading = true;
      if (!event.target.files || event.target.files.length === 0) {
        throw new Error('必须选择要上载的图像。');
      }

      const file = event.target.files[0];
      const fileExt = file.name.split('.').pop();
      const fileName = `${Math.random()}.${fileExt}`;
      const filePath = `${fileName}`;

      await this.supabase.uploadAvatar(filePath, file);
      this.upload.emit(filePath);
      this.downloadImage(filePath)
    } catch (error:any) {
      alert(error.message);
    } finally {
      this.uploading = false;
    }
  }
}</string>
Copier après la connexion
Copier après la connexion

🎜Mettre à jour le style🎜🎜🎜Vous voyez que l'interface n'est vraiment pas très élégante, mettez à jour le style pour lui donner un aspect mieux. Modifiez le fichier src/styles.css. 🎜
import {Component, Input, OnInit} from '@angular/core';
import {Profile, SupabaseService} from "../supabase.service";
import {Session} from "@supabase/supabase-js";

@Component({
  selector: 'app-account',
  template: `
      <app-avatar>
    </app-avatar>
    <div>
      <div>
        <label>邮箱</label>
        <input>
      </div>
      <div>
        <label>名称</label>
        <input>
      </div>
      <div>
        <label>网址</label>
        <input>
      </div>

      <div>
        <button>
          {{loading ? 'Loading ...' : 'Update'}}
        </button>
      </div>

      <div>
        <button>
          退出登录
        </button>
      </div>
    </div>
  `
})
export class AccountComponent implements OnInit {
  loading = false;
  profile: Profile | undefined;

  @Input() session: Session | undefined;

  constructor(private readonly supabase: SupabaseService) { }

  ngOnInit() {
    this.getProfile();
  }

  async getProfile() {
    try {
      this.loading = true;
      let {data: profile, error, status} = await this.supabase.profile;

      if (error && status !== 406) {
        throw error;
      }

      if (profile) {
        this.profile = profile;
      }
    } catch (error:any) {
      alert(error.message)
    } finally {
      this.loading = false;
    }
  }

  async updateProfile(username: string, website: string, avatar_url: string = '') {
    try {
      this.loading = true;
      await this.supabase.updateProfile({username, website, avatar_url});
      alert("修改成功")
    } catch (error:any) {
      alert(error.message);
    } finally {
      this.loading = false;
    }
  }

  async signOut() {
    await this.supabase.signOut();
  }
}
Copier après la connexion
Copier après la connexion

🎜Page d'informations sur l'utilisateur🎜🎜🎜Une fois l'utilisateur connecté , nous pouvons être autorisés à modifier les détails de leur profil et à gérer leur compte. Créez un 🎜AccountComponent à l'aide des commandes Angular CLI. 🎜 ng g c account🎜🎜src/app/account/account.component.ts🎜rrreee🎜🎜Modifiez le fichier d'entrée du projet🎜🎜🎜Maintenant que tous les composants sont prêts, mettons à jour 🎜AppComponent🎜 :🎜

src/app/app.component.ts

import {Component, OnInit} from '@angular/core';
import {SupabaseService} from "./supabase.service";

@Component({
  selector: 'app-root',
  template: `
  <div>
    <app-account></app-account>
    <ng-template>
      <app-auth></app-auth>
    </ng-template>
  </div>
  `
})
export class AppComponent implements OnInit {
  session = this.supabase.session;

  constructor(private readonly supabase: SupabaseService) { }

  ngOnInit() {
    this.supabase.authChanges((_, session) => this.session = session);
  }
}
Copier après la connexion
Copier après la connexion

完成后,在终端窗口中运行它:

npm run start
Copier après la connexion
Copier après la connexion

然后打开浏览器到 http://localhost:4200,你应该会看到完整的应用程序。

实现:上传头像及更新用户信息

每个 MemFire Cloud项目都配置了存储,用于管理照片和视频等大文件。

创建上传小组件

让我们为用户创建一个头像,以便他们可以上传个人资料照片。使用Angular CLI 命令创建AvatarComponent 。 ng g c avatar

src/app/avatar/avatar.component.ts

import {Component, EventEmitter, Input, Output} from '@angular/core';
import {SupabaseService} from "../supabase.service";
import {DomSanitizer, SafeResourceUrl} from "@angular/platform-browser";

@Component({
  selector: 'app-avatar',
  template: `
    <div>
      <img  alt="Parlons de la façon de créer des applications angulaires à l'aide de MemFire ​​​​Cloud" >
</div>
    <div></div>
    <div>
      <label>
        {{uploading ? 'Uploading ...' : 'Upload'}}
      </label>
      <input>
    </div>
  `,
})
export class AvatarComponent {
  _avatarUrl: SafeResourceUrl | undefined;
  uploading = false;

  @Input()
  set avatarUrl(url: string | undefined) {
    if (url) {
      this.downloadImage(url);
    }
  };

  @Output() upload = new EventEmitter<string>();

  constructor(
    private readonly supabase: SupabaseService,
    private readonly dom: DomSanitizer
  ) { }

  async downloadImage(path: string) {
    try {
      const {data} = await this.supabase.downLoadImage(path);
       if (data instanceof Blob) {
        this._avatarUrl = this.dom.bypassSecurityTrustResourceUrl(
          URL.createObjectURL(data)
        );
      }
    } catch (error:any) {
      console.error('下载图片出错: ', error.message);
    }
  }

  async uploadAvatar(event: any) {
    try {
      this.uploading = true;
      if (!event.target.files || event.target.files.length === 0) {
        throw new Error('必须选择要上载的图像。');
      }

      const file = event.target.files[0];
      const fileExt = file.name.split('.').pop();
      const fileName = `${Math.random()}.${fileExt}`;
      const filePath = `${fileName}`;

      await this.supabase.uploadAvatar(filePath, file);
      this.upload.emit(filePath);
      this.downloadImage(filePath)
    } catch (error:any) {
      alert(error.message);
    } finally {
      this.uploading = false;
    }
  }
}</string>
Copier après la connexion
Copier après la connexion

然后我们可以在AccountComponent html 模板的顶部添加小部件:

src/app/account/account.component.ts

import {Component, Input, OnInit} from '@angular/core';
import {Profile, SupabaseService} from "../supabase.service";
import {Session} from "@supabase/supabase-js";

@Component({
  selector: 'app-account',
  template: `
      <app-avatar>
    </app-avatar>
    <div>
      <div>
        <label>邮箱</label>
        <input>
      </div>
      <div>
        <label>名称</label>
        <input>
      </div>
      <div>
        <label>网址</label>
        <input>
      </div>

      <div>
        <button>
          {{loading ? 'Loading ...' : 'Update'}}
        </button>
      </div>

      <div>
        <button>
          退出登录
        </button>
      </div>
    </div>
  `
})
export class AccountComponent implements OnInit {
  loading = false;
  profile: Profile | undefined;

  @Input() session: Session | undefined;

  constructor(private readonly supabase: SupabaseService) { }

  ngOnInit() {
    this.getProfile();
  }

  async getProfile() {
    try {
      this.loading = true;
      let {data: profile, error, status} = await this.supabase.profile;

      if (error && status !== 406) {
        throw error;
      }

      if (profile) {
        this.profile = profile;
      }
    } catch (error:any) {
      alert(error.message)
    } finally {
      this.loading = false;
    }
  }

  async updateProfile(username: string, website: string, avatar_url: string = '') {
    try {
      this.loading = true;
      await this.supabase.updateProfile({username, website, avatar_url});
      alert("修改成功")
    } catch (error:any) {
      alert(error.message);
    } finally {
      this.loading = false;
    }
  }

  async signOut() {
    await this.supabase.signOut();
  }
}
Copier après la connexion
Copier après la connexion

恭喜!在这个阶段,您拥有一个功能齐全的应用程序!

更多编程相关知识,请访问:编程视频!!

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
2 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Repo: Comment relancer ses coéquipiers
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Parlons des métadonnées et des décorateurs dans Angular Parlons des métadonnées et des décorateurs dans Angular Feb 28, 2022 am 11:10 AM

Cet article poursuit l'apprentissage d'Angular, vous amène à comprendre les métadonnées et les décorateurs dans Angular, et comprend brièvement leur utilisation. J'espère qu'il sera utile à tout le monde !

Comment installer Angular sur Ubuntu 24.04 Comment installer Angular sur Ubuntu 24.04 Mar 23, 2024 pm 12:20 PM

Angular.js est une plateforme JavaScript librement accessible pour créer des applications dynamiques. Il vous permet d'exprimer rapidement et clairement divers aspects de votre application en étendant la syntaxe HTML en tant que langage de modèle. Angular.js fournit une gamme d'outils pour vous aider à écrire, mettre à jour et tester votre code. De plus, il offre de nombreuses fonctionnalités telles que le routage et la gestion des formulaires. Ce guide expliquera comment installer Angular sur Ubuntu24. Tout d’abord, vous devez installer Node.js. Node.js est un environnement d'exécution JavaScript basé sur le moteur ChromeV8 qui vous permet d'exécuter du code JavaScript côté serveur. Être à Ub

Explication détaillée du gestionnaire d'état d'apprentissage angulaire NgRx Explication détaillée du gestionnaire d'état d'apprentissage angulaire NgRx May 25, 2022 am 11:01 AM

Cet article vous donnera une compréhension approfondie du gestionnaire d'état NgRx d'Angular et vous présentera comment utiliser NgRx. J'espère qu'il vous sera utile !

Une brève analyse de la façon d'utiliser monaco-editor en angulaire Une brève analyse de la façon d'utiliser monaco-editor en angulaire Oct 17, 2022 pm 08:04 PM

Comment utiliser monaco-editor en angulaire ? L'article suivant enregistre l'utilisation de monaco-editor dans angulaire qui a été utilisé dans une entreprise récente. J'espère qu'il sera utile à tout le monde !

Un article explorant le rendu côté serveur (SSR) dans Angular Un article explorant le rendu côté serveur (SSR) dans Angular Dec 27, 2022 pm 07:24 PM

Connaissez-vous Angular Universel ? Cela peut aider le site Web à fournir un meilleur support SEO !

Que dois-je faire si le projet est trop gros ? Comment diviser raisonnablement les projets Angular ? Que dois-je faire si le projet est trop gros ? Comment diviser raisonnablement les projets Angular ? Jul 26, 2022 pm 07:18 PM

Le projet Angular est trop volumineux, comment le diviser raisonnablement ? L'article suivant vous expliquera comment diviser raisonnablement les projets Angular. J'espère qu'il vous sera utile !

Parlons de la façon de personnaliser le format angulaire-datetime-picker Parlons de la façon de personnaliser le format angulaire-datetime-picker Sep 08, 2022 pm 08:29 PM

Comment personnaliser le format angulaire-datetime-picker ? L'article suivant explique comment personnaliser le format. J'espère qu'il sera utile à tout le monde !

Angular + NG-ZORRO développent rapidement un système backend Angular + NG-ZORRO développent rapidement un système backend Apr 21, 2022 am 10:45 AM

Cet article partagera avec vous une expérience pratique d'Angular et apprendra comment développer rapidement un système backend en utilisant Angualr combiné avec ng-zorro. J'espère que cela sera utile à tout le monde !

See all articles