angular - 如何从 AngularFireAuth 获取 signInAnonymously 以返回 promise

标签 angular firebase promise async-await angularfire

我一直在按照 fireship.io 的教程设置条纹支付。 在 their repo's auth service ,我看到很多 observables 到 promises 的转换,大概是为了在 checkout 组件中允许非常有用和可读的 async/await 语法。 比如auth服务中存在这个方法:

getUser(): Promise<any> {
    return this.afAuth.authState.pipe(first()).toPromise();
  }

允许在组件中进行这样的调用

const user = await this.auth.getUser();

我试图从根本上允许用户向我的网络应用程序捐款,这不需要任何登录。目前,我在结帐组件中调用了 stripeCreateCharge(见下文),但这取决于 auth.getUser() 方法,我认为这意味着我需要某种登录。

因此,我在身份验证服务中创建了一个匿名登录方法,并在处理程序调用的上游调用它。

来自 auth.service.ts:

anonymousLogin() {
    console.log("anonymousLogin entered");
    // console.log('AuthIsStateResolved: ' + this.afAuth.auth.isStateResolved_);
    this.afAuth.auth.signInAnonymously()
     .then((credential) => {
       console.log("success inside callback for signInAnonymously");
       console.log(credential.user);
       // this.authState = credential;
       this.updateUserData(credential.user);
       return this.getUser();
     })
     .catch(error => console.log(error));
  }

在我的 checkout.component.ts 中:

ngOnInit() {
    this.auth.signOut();
    this.handler = StripeCheckout.configure({
      key: 'pk_live_ztqhLfPwjEf2SFC26LDmWkXr',
      locale: 'auto',
      source: async (source) => {
        this.displayThings = true;
        this.loading = true;
        console.log("got into source callback from handler in checkout.component");
        this.auth.anonymousLogin();
        const user = await this.auth.getUser();
        console.log(user);
        if(user){
          const fun = this.functions.httpsCallable('stripeCreateCharge');
          this.confirmation = await fun({ source: source.id, uid: user.uid, amount: this.amount }).toPromise();
          console.log("this.confirmation");
          console.log(this.confirmation.outcome.seller_message);
          this.loading = false;
          if(this.confirmation.outcome.seller_message === "Payment complete."){
            this.paymentStatus = this.confirmation.outcome.seller_message + " Thank you!";
          } else{
            this.paymentStatus = this.confirmation.outcome.seller_message;
          }
        } else{
          console.log("ack never happened");
        }
      }
    });
  }

特别注意线条

        this.auth.anonymousLogin();
        const user = await this.auth.getUser();
        console.log(user);

上面,我看到 this.auth.anonymousLogin() 直到 const user = await this.auth.getUser( ); 被调用,所以我们有一个异步问题,控制台输出证明了这一点:

enter image description here

我的问题:有没有一种方法可以修改 anonymousLogin() 以在它完成时返回一个 promise,这样我就可以继续使用 async/await 语法,并有类似的东西,

        const loggedInStatus = await this.auth.anonymousLogin();
        if(loggedInStatus){
            const user = await this.auth.getUser();
            console.log(user);
            // More stuff in here...
        }

或者,对于如何处理这整件事,有更好的建议吗?

2019 年 12 月 17 日更新:

当我将 return 添加到我的 signInAnonymously 方法时,它会在我的 checkout.component.ts 中返回 undefined:

auth.service.ts

...
anonymousLogin() {
    console.log("anonymousLogin entered");
    // console.log('AuthIsStateResolved: ' + this.afAuth.auth.isStateResolved_);
    return this.afAuth.auth.signInAnonymously()
     .then((credential) => {
       console.log("success inside callback for signInAnonymously");
       console.log(credential.user);
       // this.authState = credential;
       this.updateUserData(credential.user);
       // return this.getUser();
     })
     .catch(error => console.log(error));
  }

checkout.component.ts

...
const loggedInStatus = await this.auth.anonymousLogin();
        console.log("test user");
        console.log(loggedInStatus);
        const user = await this.auth.getUser();
        console.log(loggedInStatus);
        //below not updated yet
        if(user){
          const fun = this.functions.httpsCallable('stripeCreateCharge');
          this.confirmation = await fun({ source: source.id, uid: user.uid, amount: this.amount }).toPromise();
          console.log("this.confirmation");
          console.log(this.confirmation.outcome.seller_message);
          this.loading = false;
          if(this.confirmation.outcome.seller_message === "Payment complete."){
            this.paymentStatus = this.confirmation.outcome.seller_message + " Thank you!";
          } else{
            this.paymentStatus = this.confirmation.outcome.seller_message;
          }
        } else{
          console.log("ack never happened");
        }
...

enter image description here

最佳答案

为了创建合适的 Promise 链,您需要:

  • 返回一个 Promise

  • 通过 .then 处理程序链传递结果

所以你的代码应该是这样的:

anonymousLogin() {
    return this.afAuth.auth.signInAnonymously()
    ^^^^^^
   add this

     .then((credential) => {
       return this.getUser();
      ^^^^^^
 return smth in then callback
     })
     ...
}

关于angular - 如何从 AngularFireAuth 获取 signInAnonymously 以返回 promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59311973/

相关文章:

swift - Firebase snapshot.key 不返回实际 key ?

javascript - Firebase - 需要修复 javascript sdk 身份验证错误

javascript - Youtube API、NodeJS 和 Promises 的问题

android - 在 React Native 0.59 上将目标 sdk 升级到 29

angular - 如何使用 TypeScript 返回正确的 Promise

angular - 以 Angular react 形式动态设置文本区域禁用

Angular http指南错误处理 - 错误?

javascript - Promise 的返回值不稳定

javascript - vue-resource: 拦截ajax错误时捕获 "Uncaught (in promise)"

javascript - 如何在另一个组件中获取指令/组件实例?