LoginSignup
2
1

More than 3 years have passed since last update.

firestoreのsetトランザクション処理

Last updated at Posted at 2019-12-15

はじめに

firestoreにリレーションを持ってデータを新規作成する際のトランザクションの方法がのっていなかったのでその時の解決策を共有します

ドキュメント構成

userがたくさんのeventを持つというようなドキュメント構成となっています
user->event(1対n)
スクリーンショット 2019-12-12 13.05.41.png
スクリーンショット 2019-12-12 13.05.53.png

解決法

// 独自でIDを生成する関数
autoId = model => {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
  let autoId = ''
  for (let i = 0; i < 20; i++) {
    autoId += chars.charAt(Math.floor(Math.random() * chars.length))
  }
  return autoId
}


saveNewEvent = async (title, body, uid, navigation) => {
  const db = firebase.firestore()
  const timestamp = firebase.firestore.Timestamp.now()

  const newEventId = autoId('events')
  const eventRef = db.collection('events').doc(newEventId)
  const userRef = db.collection('users').doc(uid)

  // トランザクション開始
  db.runTransaction(async transaction => {
    await Promise.all(transaction.get(userRef), transaction.get(eventRef))
    transaction.set(eventRef, {
      userId: uid,
      title: title,
      body: body,
      createdAt: timestamp,
      updatedAt: timestamp
    })

    transaction.update(userRef, {
      events: firebase.firestore.FieldValue.arrayUnion(newEventId),
      updatedAt: timestamp
    })
  }) // トランザクション完了
    .then(() => {
        // 完了後の処理
    })
    .catch(error => {
      console.log(error)
    })
}

解説

firestoreでトランザクションを行うときは先に作成コレクション作成前にidを指定する必要があるそうなので今回はautoId()というメソッドを作って独自でIDを生成してそのIDをもとにしてコレクションを作成しています。

まとめ

トランザクション管理は一貫性を持ったデータを保持するためには絶対に必要なので丁寧にやりたいところですね!

参考文献

2
1
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
2
1