4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Firestoreの公式ドキュメントに載っているコードをasync/awaitで書き直してみる

Posted at

はじめに

Firebaseのデータストアの1つであるFirestoreの公式ドキュメントのサンプルコードが全てPromiseチェーンになっているので、一部のコードをasync/awaitで書き直してみます。

Promiseチェーンとは

hoge.js
var docRef = db.collection("cities").doc("SF");

docRef.get().then((doc) => {
    if (doc.exists) {
        console.log("Document data:", doc.data());
    } else {
        // doc.data() will be undefined in this case
        console.log("No such document!");
    }
}).catch((error) => {
    console.log("Error getting document:", error);
});

上記のような then で非同期処理の結果を受け取る方法をPromiseチェーンと呼びます(正式名称かは不明)。

この記述を行うと、連続して非同期処理を行った時にコードの可読性が低下する要因となります。
例えば、非同期処理が3連続すると以下のようなコードになります。

fuga.js
var docRef = db.collection("cities").doc("SF");
var docRef2 = db.collection("cities").doc("LA");
var docRef3 = db.collection("cities").doc("DC");

docRef.get().then((doc) => {
  if (doc.exists) {
    console.log("Document data:", doc.data());
  } else {
    // doc.data() will be undefined in this case
    console.log("No such document!");

    // データがなかった場合、docRef2のデータを取得する
    docRef2.get().then((doc) => {
      if (doc.exists) {
        console.log("Document data:", doc.data());
      } else {
        // doc.data() will be undefined in this case
        console.log("No such document!");

        // データがなかった場合、docRef3のデータを取得する
        docRef3.get().then((doc) => {
          if (doc.exists) {
            console.log("Document data:", doc.data());
          } else {
            // doc.data() will be undefined in this case
            console.log("No such document!");
          }
        }).catch((error) => {
          console.log("Error getting document:", error);
        })
      }
    }).catch((error) => {
      console.log("Error getting document:", error);
    });
  }
}).catch((error) => {
    console.log("Error getting document:", error);
});

このように連続したPromiseチェーンはコードのネストが深くなりやすく、可読性が低くなります。

ドキュメントを取得する

公式ドキュメントのコード

test.firebase.js
var docRef = db.collection("cities").doc("SF");

docRef.get().then((doc) => {
  if (doc.exists) {
    console.log("Document data:", doc.data());
  } else {
    // doc.data() will be undefined in this case
    console.log("No such document!");
  }
}).catch((error) => {
  console.log("Error getting document:", error);
});

async/awaitを使用したコード

refactoring.firebase.js
var docRef = db.collection("cities").doc("SF");

const getDoc = async() => {
  try {
    const doc = await docRef.get();
    if (doc.exists) {
      console.log("Document data:", doc.data());
    } else {
      // doc.data() will be undefined in this case
      console.log("No such document!");
    }
  } catch(error) {
    console.log("Error getting document:", error);
  }
}

// この処理は非同期で実行される
getDoc();

3連続した非同期処理をasync/awaitに書き換える

refactoring.firebase.js
var docRef = db.collection("cities").doc("SF");
var docRef2 = db.collection("cities").doc("LA");
var docRef3 = db.collection("cities").doc("DC");

const getDoc = async() => {
  try {
    const doc = await docRef.get();
    if (doc.exists) {
      console.log("Document data:", doc.data());
      return;
    }
    // doc.data() will be undefined in this case
    console.log("No such document!");

    // データがなかった場合、docRef2のデータを取得する
    const doc2 = await docRef2.get();
    if (doc.exists) {
      console.log("Document data:", doc2.data());
      return;
    }
    // doc.data() will be undefined in this case
    console.log("No such document!");

    // データがなかった場合、docRef3のデータを取得する
    const doc3 = await docRef3.get();
    if (doc.exists) {
      console.log("Document data:", doc3.data());
      return;
    }
    // doc.data() will be undefined in this case
    console.log("No such document!");
  } catch(error) {
    console.log("Error getting document:", error);
  }
}

// この処理は非同期で実行される
getDoc();

Promiseチェーンが1つの場合は、ネストがあまり深くならないのでasync/awaitの恩恵をあまり感じませんが、複数の処理を実行する時は、ネストが深くなるのを抑えてくれます。

コレクションから複数のドキュメントを取得する

公式ドキュメントのコード

test.firebase.js
db.collection("cities").where("capital", "==", true)
  .get()
  .then((querySnapshot) => {
    querySnapshot.forEach((doc) => {
      // doc.data() is never undefined for query doc snapshots
      console.log(doc.id, " => ", doc.data());
    });
  })
  .catch((error) => {
    console.log("Error getting documents: ", error);
  });

async/awaitを使用したコード

refactoring.firebase.js
const getDocs = async() => {
  try {
    const querySnapshot = await db.collection("cities").where("capital", "==", true);
    querySnapshot.forEach((doc) => {
      // doc.data() is never undefined for query doc snapshots
      console.log(doc.id, " => ", doc.data());
    })
  } catch(error) {
    console.log("Error getting documents: ", error);
  }
}

// この処理は非同期で実行される
getDocs();

まとめ

Firebaseのコードは全てPromiseチェーンで記述されているため、何も考えずにコードを書いていくと、ネストが深くなりがちです。
async/awaitを使用して、ネストが少ないコードを心がけましょう!

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?