Firebase: должны ли Promise или Observable использоваться в проекте Angular? - PullRequest
1 голос
/ 03 ноября 2019

Я только начал изучать Angular. Если я использовал Firebase для авторизации пользователя, то лучше ли использовать Promise или Observable?

Как мне нужно изменить URL, если при попытке войти через Facebook я получаю сообщение об ошибке:

Невозможно загрузить URL: домен этого URL не являетсявключен в список доменов приложений. Чтобы загрузить этот URL, добавьте все домены и дочерние домены вашего приложения в поле «Приложения» в настройках приложения.

1 Ответ

0 голосов
/ 03 ноября 2019

RxJS является более гибкой и мощной средой, чем Promises для асинхронного программирования. При этом предпочтительно использовать Observables или Promises при работе с API Firebase.

AngularFire был разработан для упрощения интеграции Firebase в проекты Angular. В API AngularFire используется Observables, а не Promises, поскольку RXJS является де-факто стандартом углового асинхронного программирования.

Если вы хотите предоставить собственный RXJS API для Firebase, одним из вариантов будет созданиеУгловой сервис. В приведенном ниже примере показано, как можно обернуть функцию Firebase signInWithCustomToken, которая возвращает Promise<UserCredential>, и преобразовать ее, чтобы получить Observable<UserCredential>.

firebase-auth.service.ts

import { Injectable, Optional } from '@angular/core'
import { HttpClient } from '@angular/common/http'
import * as firebase from 'firebase/app'
import 'firebase/auth'

import { BehaviorSubject } from 'rxjs'
import { concatMap } from 'rxjs/operators'


@Injectable({
  providedIn: 'root'
})
export class FirebaseAuthService {
  public app: firebase.app.App;
  public auth: firebase.auth.Auth;
  public user$: BehaviorSubject<firebase.User> = new BehaviorSubject(null);

  // Note: FirebaseConfig is a class to enable injecting the Firebase app 
  // initialization params when providing the service in app.module.ts.
  constructor(@Optional() fb_config: FirebaseConfig, private http: HttpClient) {
    // https://firebase.google.com/docs/reference/js/firebase.app.App
    this.app = firebase.initializeApp(fb_config);
    this.auth = firebase.auth(this.app);

    this.auth.onAuthStateChanged(
      (user: firebase.User) => {
        if (user) {
          this.user$.next(user);
          console.log('User signed in');
        } else {
          this.user$.next(null);
          console.log('User signed out');
        }
      },
      (error: firebase.auth.Error) => {
        // handle error
      }
    )
  }

  public signInWithCustomToken(uid: string, secret_auth_code: string): 
      Observable<firebase.auth.UserCredential> {
    const params = new HttpParams()
      .set('uid', uid)
      .set('secret', secret_auth_code)
    return this.http.get('/get-custom-token', {params: params}).pipe(
      concatMap((json: any) => from(this.auth.signInWithCustomToken(json['custom_token'])))
    )
  }

  // ...
}

Компонент

@Component({
  moduleId: module.id,
  selector: 'my-component',
  templateUrl: 'my.component.html',
  styleUrls: ['my.component.css']
})
export class MyComponent implements OnInit {
  constructor(private authService: FirebaseAuthService) {}
  // ...
}

Шаблон

<ng-container *ngIf="( authService.user$ | async ) as user">
  <div>Hello {{user.displayName}}</div>
</ng-container>
...