💡

【TypeScript】RxJSでFirestoreのリアルタイムデータ処理を分離する

2022/12/22に公開

はじめに

Firestoreでデータ取得をする処理を書くときに、repository等で処理して、データのやり取りをしたいと思ったことはないでしょうか。

1度だけ取得する場合は、Promise型で実装しても問題ありませんが、リアルタイムで取得しようと思うと工夫が必要となります。

今回は、RxJSというライブラリを使用して、Firestoreでリアルタイム取得したデータを複数回やりとりする方法を紹介します。

RxJSとは?

RxJSとは、Observableと呼ばれるデータ構造を提供してくれるライブラリになります。
https://rxjs.dev/guide/overview

Observableは非同期処理を行う際に使用するものになりますが、
Promiseと異なる点は、Promiseが1度だけデータ送信をするのに対し、Ovservableでは複数回データを送信することができます。

実践

ここでは、Firestoreでデータの更新があった場合、console.log()でそのデータを表示するという簡単なプログラムを、RxJSを使用しない場合と、使用した場合の2パターンを作成します。

RxJSを使用しない場合

const db = firebase.firestore();
const collection = db.collection(コレクションパス);
collection.onSnapshot((v) => {
  console.log(v);
});

onSnapshot()で、Firestoreのコレクションの更新を監視し、更新があったらconsole.log()で表示しています。

この問題点として、onSnapshot()内に処理を書かないといけないことです。
また、onSnapshot()は戻り値がvoidであるため、データの返却をすることもできません。

RxJSを使用した場合

// データを継続的に送信
function watchValue(): Observable<any> {
  const db = firebase.firestore();
  const collection = db.collection(コレクションパス);
  const obs = new Observable((subscriber: Subscriber<any>) => {
    collection.onSnapshot((v) => {
      subscriber.next(v); // データを送信する
    });
  });
  return obs;
}

// データを継続的に取得
const obs = watchValue();
obs.subscribe((v) => {
  console.log(v);
});

RxJSを使用していない場合と異なり、データを別の場所へ送信することができるようになりました。
このコードについて簡単に説明すると、

watchValue()内では、まず、データ受け渡し用のObservableを生成し、その中のSubscriberを引数にもつ関数内で、Firestoreのデータ監視を行い、更新があると、subscriber.next()でデータの送信を行っています。

取得している側の処理では、データ受け渡し用のObservablewatchValue()で取得し、それに対してsubscribe()することでデータの取得を行っています。

Discussion