0

I have used promise inside the subscribe/observable as shown below. But it gives errors. can you tell me how to construct or design the code properly here?

async loginWithGoogle(): Promise<void> {
    const result = await this.afAuth.auth.signInWithPopup(new firebase.auth.GoogleAuthProvider());
    const userId: string = result.additionalUserInfo.profile.id;
    const userProfile: AngularFirestoreDocument<UserProfile> = this.fireStore.doc(`userProfile/${userId}`);
    const userProfiles: AngularFirestoreCollection<UserProfile> = this.fireStore.collection('userProfile/', ref => ref.where('email', '==', result.additionalUserInfo.profile.email));
    const userProfiles$: Observable<UserProfile[]> = userProfiles.valueChanges();

    userProfiles$.subscribe(async res => { // problem is here
      if (res.length == 0) {
        await userProfile.set({
          id: userId,
          email: result.additionalUserInfo.profile.email,
          creationTime: moment().format(),
          lastSignInTime: moment().format()
        });
      }
    });
  }

Stack 1:

core.js:1350 ERROR Error: FIRESTORE (4.7.0) INTERNAL ASSERTION FAILED: AsyncQueue is already failed: The transaction was aborted, so the request cannot be fulfilled.
    at fail (assert.js:33)
    at AsyncQueue.schedule (async_queue.js:50)
    at dispatchIfStillActive (persistent_stream.js:303)
    at StreamBridge.wrappedOnClose (persistent_stream.js:325)
    at StreamBridge.callOnClose (stream_bridge.js:54)
    at webchannel_connection.js:220
    at X.<anonymous> (webchannel_connection.js:195)
    at Bb (index.js:22)
    at X.g.dispatchEvent (index.js:20)
    at Pe.Ca (index.js:94)

Stack 2:

core.js:1350 ERROR Error: Uncaught (in promise): AbortError: The transaction was aborted, so the request cannot be fulfilled.
    at c (polyfills.js:3)
    at c (polyfills.js:3)
    at polyfills.js:3
    at t.invokeTask (polyfills.js:3)
    at Object.onInvokeTask (core.js:4617)
    at t.invokeTask (polyfills.js:3)
    at r.runTask (polyfills.js:3)
    at o (polyfills.js:3)
    at e.invokeTask (polyfills.js:3)
    at i.isUsingGlobalCallback.invoke (polyfills.js:3)
Mark van Straten
  • 9,287
  • 3
  • 38
  • 57
Sampath
  • 63,341
  • 64
  • 307
  • 441
  • why not use observable operators instead? Not sure you can send a promise function in subscribe at all – Suraj Rao Dec 08 '17 at 09:14
  • I didn't get you? Can you show `code` for that? @SurajRao – Sampath Dec 08 '17 at 09:19
  • something like https://stackoverflow.com/questions/34728827/rxjs-if-with-observable-as-conditional only with `if` and `switchMap` – Suraj Rao Dec 08 '17 at 09:21
  • Can't I convert it to `promise` using `toPromise`? I have tried like this.But still, it works as observable. In other words that method fires 2 times. One is for the `0` and other is for the `1` where the database has been updated use case.Where is the issue @SurajRao `userProfiles$.map(async res => { if (res.length == 0) { await userProfile.set({ id: userId, }); } }) .toPromise() .catch(err => { });` – Sampath Dec 08 '17 at 09:43
  • you can... I was saying about a promise function in _subscribe_. – Suraj Rao Dec 08 '17 at 09:47
  • Can you show me how to do that? I mean convert it to `promise`. I did like above. But still, it works as `observable`.Any clue? @SurajRao At this moment it fires 2 times. – Sampath Dec 08 '17 at 10:02
  • you are doing reverse.. you can either convert `userProfile$` to a promise using `userProfile$.toPromise()` or convert the promise to observable using `fromPromise()`. – Suraj Rao Dec 08 '17 at 10:04
  • Actually, I have used this method. @SurajRao Is that wrong? https://stackoverflow.com/a/36777294/1077309 – Sampath Dec 08 '17 at 10:05
  • Your answer didn't work. Any alternative? @SurajRao – Sampath Dec 08 '17 at 10:26
  • I deleted it because on closer look at stack 1.. this may be an issue with firestore. – Suraj Rao Dec 08 '17 at 10:27
  • No.It is working fine. This method works fine. But the problem here is it still works as `observable`.`userProfiles$.map(async res => { if (res.length == 0) { await userProfile.set({ id: userId, }); } }) .toPromise() .catch(err => { });`. Inother words it fires 2 times. @SurajRao – Sampath Dec 08 '17 at 10:28
  • are you sure `set` returns a promise? – Suraj Rao Dec 08 '17 at 10:31
  • This is the method signature. It is a `firestore` method. @SurajRao `(method) AngularFirestoreDocument.set(data: UserProfile, options?: firebase.firestore.SetOptions): Promise` – Sampath Dec 08 '17 at 10:35
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/160783/discussion-between-suraj-rao-and-sampath). – Suraj Rao Dec 08 '17 at 10:36
  • Did you find a solution? – Murhaf Sousli Jun 12 '18 at 23:20

0 Answers0