Flutter + Firestore 同じドキュメントIDが存在するかチェックしてから保存


ドキュメントIDを指定して保存する時、ダブってないか確認したい

FirestoreでドキュメントIDを指定して保存するときってありますよね?

例えば映画情報を取得できるAPIを使ってた場合、APIの中で既に映画に対して割り振られているIDをそのままドキュメントIDとして使いたい、といったパターンがあるかと思います。

そういった時に「ドキュメントIDが既に存在するかチェックしてから保存」という処理にしたいと思い、調べてみました

前提

FlutterとFirebaseの連携部分は省きます。

環境は下記の通り

pubspec.yaml
environment:
  sdk: ">=2.7.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  firebase_core: "0.7.0"
  firebase_auth: "^0.20.1"
  cloud_firestore: "^0.16.0+1"
  firebase_storage: "^7.0.0"
  cloud_functions: ^0.9.0

ドキュメントIDが既に存在するかどうかをチェックして、存在しなければ新たにデータを保存する

ここではAPIから取得したmovieIdという値を、そのままドキュメントIDとして使用します。

「映画をマイリストに保存する」みたいな処理をイメージして頂けるとわかりやすいかと!

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';

class AddMovieButton extends StatelessWidget {

final int movieId;
final title;
AddMovieButton(this.movieId, this.title);

  final FirebaseFirestore firestore = FirebaseFirestore.instance;
  final FirebaseAuth auth = FirebaseAuth.instance;

void _addMovie(BuildContext ctx) async {
    final uid = auth.currentUser.uid;
    final _userRef = firestore.collection('users/${uid}/movies');
    final _movieRef =
        firestore.collection('users/${uid}/movies').doc(movieId.toString());
    await _movieRef.get().then((docSnapshot) => {
          if (docSnapshot.exists)
            {
              // 既に登録されているドキュメントの場合
              print('追加しない')
            }
          else
            {
              // 登録されてない新しいドキュメントの場合
              _userRef
                  .doc(movieId.toString())
                  .set({'id': movieId, 'title': title})
                  .then(
                    (value) => print('追加しました'),
                  )
                  .catchError((error) {
                    print('追加失敗!')
                  }),
            }
        });
  }

// 省略

}

あとはprintの部分を好みに合わせて、アラートやSnackBarにすると良いかと

参考