# How to make an Observable from a query in Firebase?

**URL:** <https://forum.ionicframework.com/t/how-to-make-an-observable-from-a-query-in-firebase/178575>\
**Category:** Ionic Framework\
**Created:** [November 27, 2019, 6:00pm UTC](https://forum.ionicframework.com/t/how-to-make-an-observable-from-a-query-in-firebase/178575 "2019-11-27T18:00:36Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![nairdagui](https://avatars.discourse-cdn.com/v4/letter/n/77aa72/32.png) [@nairdagui](https://forum.ionicframework.com/u/nairdagui)\
**Post date:** [November 27, 2019, 6:00pm UTC](https://forum.ionicframework.com/t/how-to-make-an-observable-from-a-query-in-firebase/178575/1 "2019-11-27T18:00:37Z")

</div>

This is my original code where the posts is only an array. My problem here is that it does not auto update on view when the data changes.

```auto
posts = [];
loadPosts() {
    this.user.getFollowedGroups().subscribe((result) => {
      this.groupsFollowed = result.following;
      this.postsCollection.ref.where('gid', 'in', this.groupsFollowed).get().then(res => {
          res.docs.forEach(doc => {
            let obj = doc.data();
            obj["id"] = doc.id;
            this.posts.push(obj);
          });
        });
    });
  }

```

So I am trying to save it on an observable instead. This is how I do it on other services which I dont use `where query`. I tried mixing it up and putting the query inside the queryFn,

```auto
followedPostsCollection: AngularFirestoreCollection<Post>;
posts: Observable<Post[]>;
loadPosts() {
    this.user.getFollowedGroups().subscribe((result) => {
      this.groupsFollowed = result.following;
      this.followedPostsCollection = this.afs.collection<Post>('announcements', ref => ref.where('gid', 'in', this.groupsFollowed));
      this.posts = this.followedPostsCollection.snapshotChanges().pipe(
        map(actions =>
          actions.map(a => {
            const data = a.payload.doc.data();
            const id = a.payload.doc.id;
            return { id, ...data };
          })
        )
      );
    });
  }

getPosts(): Observable<Post[]> {
    return this.posts;
  }

```

but this code gives me undefined posts when I subscribe with it. Where do I go wrong and how to make it work? Or should I just use `.onSnapshot` or `.then` like what I did on the first one but I cant seem to save it on an observable.

---

<div class="post-metadata">

**Author:** ![rapropos](https://sea1.discourse-cdn.com/ionicframework/user_avatar/forum.ionicframework.com/rapropos/32/100227_2.png) [@rapropos](https://forum.ionicframework.com/u/rapropos)\
**Post date:** [November 27, 2019, 10:34pm UTC](https://forum.ionicframework.com/t/how-to-make-an-observable-from-a-query-in-firebase/178575/2 "2019-11-27T22:34:40Z")

</div>

There is a fundamental unknowable regarding timing that is baked into this code. `getPosts` is returning a service property, yet that service property is assigned to in a subscription. There is no easy way for `getPosts` to know, yet alone do anything with the knowledge about, when that assignment is going to occur.

I painted myself into corners like this many times, and eventually settled on the following rule, which in addition to making for (IMHO) clearer code, makes it much harder to step on such rakes:

> All code that interacts with futures should either produce one or consume one, but never try to do both things.

A related rule:

> The first word of a future-producing function should generally be `return`.

If you haven’t seen [this taxonomy of future-producers](https://forum.ionicframework.com/t/ionic-app-loading-sequence/100109/11) before, check it out. Based on its name and what it seems to be trying to do, `loadPosts` is in a tough spot. It’s really a category C, but it’s written like a category A. In fact, `loadPosts` and `getPosts` can’t really be disentangled, so I would combine them, and along the way totally get rid of all the instance properties in the service. There are ways to preserve them so that they make more sense, but for now I think things will be clearer if we can design away any potential sources of stale data.

I’m also going to dumb down your `User` class for philosophical reasons that can be discussed later if you care, but aren’t particularly germane here. Instead of the user itself generating followed groups, the service is going to do that given a POD `User`.

```auto
followedGroups(user: User): Observable<Group[]> {
}

postsForUser(user: User): Observable<Post[]> {
  return this.followedGroups(user).pipe(
    switchMap(groups => this.afs.collection<Post>('announcements', ref => ref.where('gid', 'in', groups).snapshotChanges()),
    map(actions => actions.map(a => {
      const data = a.payload.doc.data();
      const id = a.payload.doc.id;
      return { id, ...data };
    })));
}

```

---

<div class="post-metadata">

**Author:** ![nairdagui](https://avatars.discourse-cdn.com/v4/letter/n/77aa72/32.png) [@nairdagui](https://forum.ionicframework.com/u/nairdagui)\
**Post date:** [November 29, 2019, 12:19pm UTC](https://forum.ionicframework.com/t/how-to-make-an-observable-from-a-query-in-firebase/178575/3 "2019-11-29T12:19:33Z")

</div>

> [@rapropos](#):
>
> All code that interacts with futures should either produce one or consume one, but never try to do both things.

Okay thanks, I will take note of this.

I was trying to follow the tutorial here [How to Create a Simple Ionic 4 Firebase App with AngularFire | Devdactic](https://devdactic.com/ionic-4-firebase-angularfire/) where the firebase data was loaded in the constructor and use a function to return that observable. But as per your advise I will just merge those two and load the firebase data on function call.

> [@rapropos](#):
>
> I’m also going to dumb down your `User` class for philosophical reasons that can be discussed later if you care,

And what should I do with user as parameter? For authentication or for filter? And how? Btw, I am calling the user function because I am trying to restrict myself as calling collection specific to their services. Thats why I am calling the user service to query the user collection. Or am I doing that wrong? Do enlighten me please.

---

<div class="post-metadata">

**Author:** ![rapropos](https://sea1.discourse-cdn.com/ionicframework/user_avatar/forum.ionicframework.com/rapropos/32/100227_2.png) [@rapropos](https://forum.ionicframework.com/u/rapropos)\
**Post date:** [November 29, 2019, 9:47pm UTC](https://forum.ionicframework.com/t/how-to-make-an-observable-from-a-query-in-firebase/178575/4 "2019-11-29T21:47:11Z")

</div>

> [@nairdagui](#):
>
> what should I do with user as parameter?

I would move whatever your existing `User.getFollowedGroups` does out of `User` and into this service as `Service.followedGroups(user)`. So, instead of:

```auto
getFollowedGroups(): Observable<Group[]> {
  return whatever.frobulate(this.foo);
}

```

…

```auto
followedGroups(user: User): Observable<Group[]> {
  return whatever.frobulate(user.foo);
}

```

> [@nairdagui](#):
>
> Thats why I am calling the user **service** to query the user collection

Then perhaps I misunderstood. I assumed something called “user” represented an actual user, not a service. If in fact it’s another service, then I see no problem with the way you’ve organized it now, but I do wonder how a `UserService` would know how to implement something like `getFollowedGroups` without knowing what user we are caring about.

---

<div class="post-metadata">

**Author:** ![nairdagui](https://avatars.discourse-cdn.com/v4/letter/n/77aa72/32.png) [@nairdagui](https://forum.ionicframework.com/u/nairdagui)\
**Post date:** [December 10, 2019, 5:58am UTC](https://forum.ionicframework.com/t/how-to-make-an-observable-from-a-query-in-firebase/178575/5 "2019-12-10T05:58:59Z")

</div>

Sorry for the late reply. One last question, between calling firestore collection in service constructor or by calling a function, which is better and why? Because my original code calls the collection inside constructor and call the result by function call, and your answer

> [@rapropos](#):
>
> In fact, `loadPosts` and `getPosts` can’t really be disentangled,

tells me to just merge it and call it by function call.

---

<div class="post-metadata">

**Author:** ![rapropos](https://sea1.discourse-cdn.com/ionicframework/user_avatar/forum.ionicframework.com/rapropos/32/100227_2.png) [@rapropos](https://forum.ionicframework.com/u/rapropos)\
**Post date:** [December 10, 2019, 8:24pm UTC](https://forum.ionicframework.com/t/how-to-make-an-observable-from-a-query-in-firebase/178575/6 "2019-12-10T20:24:26Z")

</div>

> [@nairdagui](#):
>
> between calling firestore collection in service constructor or by calling a function, which is better and why?

The clearest rule I can think of here is this:

Is it provable that everything being done in the whole `getPosts`/`loadPosts` world doesn’t change over the life of an app run? For example, can users change which groups they follow in the app? Can the user we’re concerned with change?

If it’s provable that everything is known and constant at app startup, then the service constructor is a viable option. Otherwise, I wouldn’t consider it so.

---

<div class="post-metadata">

**Author:** ![nairdagui](https://avatars.discourse-cdn.com/v4/letter/n/77aa72/32.png) [@nairdagui](https://forum.ionicframework.com/u/nairdagui)\
**Post date:** [December 11, 2019, 1:03pm UTC](https://forum.ionicframework.com/t/how-to-make-an-observable-from-a-query-in-firebase/178575/7 "2019-12-11T13:03:14Z")

</div>

Okay I get it now. I really learn a lot from you. Thank you.
