uioporqwerty
uioporqwerty

Reputation: 1158

How to observe changes made to a function that calls firestore onSnapShot?

I have the following function:

public GetExercisePosts(user: User): ExercisePost[] {
    const exercisePosts = new Array<ExercisePost>();
    firebase.firestore().collection('exercise-posts').where('created-by', '==', user.Id).onSnapshot((results) => {
      results.forEach((postDoc) => {
        const exercisePost = Deserializer.DeserializeExercisePost(postDoc);
        if (exercisePost) {
          exercisePosts.push(exercisePost);
        }
      });
    });
    return exercisePosts;
  }

Another react component will call the function like so:

public async componentDidMount() {
    const personalExercisePosts = this.exerciseService.GetExercisePosts(this.state.currentUser);
    this.setState({ personalExercisePosts });
  }

This works great the first time, however that original method of GetExercisePosts doesn't get fired once the snapshot changes, which makes sense since componentDidMount is only called once in a component's lifecycle. However, I do know that the snapshot function is called because when I add a record through Firestore admin console, it logs the new data.

How can I observe changes made to that snapshot? Or maybe have the snapshot emit a change that the component can listen for? As I understand it, I could introduce Redux, but I would like to avoid that if possible at this juncture.

Upvotes: 1

Views: 1192

Answers (1)

Ricardo Smania
Ricardo Smania

Reputation: 3149

You can register a callback instead of returning, that way it will fire whenever the snapshot changes, something like this:

public GetExercisePosts(user: User, callback: (results: ExercisePost[]) => void) {
    const exercisePosts = new Array<ExercisePost>();
    firebase.firestore().collection('exercise-posts').where('created-by', '==', user.Id).onSnapshot((results) => {
      results.forEach((postDoc) => {
        const exercisePost = Deserializer.DeserializeExercisePost(postDoc);
        if (exercisePost) {
          exercisePosts.push(exercisePost);
        }
      });
      callback(exercisePosts);
    });
  }

  public async componentDidMount() {
    const personalExercisePosts = this.exerciseService.GetExercisePosts(this.state.currentUser, (posts) {
      this.setState({ posts });
    });
  }

Upvotes: 2

Related Questions