前回は、Flutterのパッケージであるget_itとcloud_firestoreを使い、Firebaseのデータベースにデータを追加しました。

今回は、Firebase Cloud Firestoreのデータを削除します。

以前作成したコードは、こちらです。

pagesフォルダ home.dart

import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:test_form2/services/firebase_service.dart';

class Home extends StatefulWidget {
  Home({Key? key}) : super(key: key);

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  FirebaseService? _firebaseService;

  @override
  void initState() {
    super.initState();
    _firebaseService = GetIt.instance.get<FirebaseService>();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: StreamBuilder(
          stream: _firebaseService!.getBooks(),
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            if (snapshot.hasData) {
              List books =
                  snapshot.data!.docs.map((doc) => doc.data()).toList();

              return ListView.builder(
                itemCount: books.length,
                itemBuilder: (BuildContext context, int index) {
                  Map book = books[index];
                  return Column(
                    children: [
                      Text(book['title'], style: TextStyle(fontSize: 24)),
                      Text(book['author'], style: TextStyle(fontSize: 18)),
                    ],
                  );
                },
              );
            } else {
              return const Center(
                child: CircularProgressIndicator(),
              );
            }
          },
        ),
      ),
    );
  }
}

servicesフォルダ firebase_service.dart

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

class FirebaseService {
  FirebaseAuth _auth = FirebaseAuth.instance;
  FirebaseFirestore _database = FirebaseFirestore.instance;

  FirebaseService();

  Future<bool> registerUser({
    required String email,
    required String password,
  }) async {
    try {
      UserCredential _userCredential = await _auth
          .createUserWithEmailAndPassword(email: email, password: password);
      return true;
    } catch (e) {
      print(e);
      return false;
    }
  }

  Future<bool> loginUser({
    required String email,
    required String password,
  }) async {
    try {
      UserCredential _userCredential = await _auth.signInWithEmailAndPassword(
          email: email, password: password);
      if (_userCredential.user != null) {
        return true;
      } else {
        return false;
      }
    } catch (e) {
      print(e);
      return false;
    }
  }

  Stream<QuerySnapshot> getBooks() {
    return _database
        .collection('books')
        .orderBy('timestamp', descending: true)
        .snapshots();
  }

  Future<bool> postBook({required String title, String? author}) async {
    try {
      await _database.collection('books').add(
        {
          'title': title,
          'author': author,
          'timestamp': Timestamp.now(),
        },
      );
      return true;
    } catch (e) {
      print(e);
      return false;
    }
  }
}

image2

まずは、Cloud Firestoreのデータを削除するために、serviceフォルダのfirebase_service.dartにdeleteBook関数を作成します。

class FirebaseService {
  FirebaseAuth _auth = FirebaseAuth.instance;
  FirebaseFirestore _database = FirebaseFirestore.instance;

  FirebaseService();

  Future<bool> registerUser({
    required String email,
    required String password,
  }) async {
    try {
      UserCredential _userCredential = await _auth
          .createUserWithEmailAndPassword(email: email, password: password);
      return true;
    } catch (e) {
      print(e);
      return false;
    }
  }

  Future<bool> loginUser({
    required String email,
    required String password,
  }) async {
    try {
      UserCredential _userCredential = await _auth.signInWithEmailAndPassword(
          email: email, password: password);
      if (_userCredential.user != null) {
        return true;
      } else {
        return false;
      }
    } catch (e) {
      print(e);
      return false;
    }
  }

  Stream<QuerySnapshot> getBooks() {
    return _database
        .collection('books')
        .orderBy('timestamp', descending: true)
        .snapshots();
  }

  Future<bool> postBook({required String title, String? author}) async {
    try {
      await _database.collection('books').add(
        {
          'title': title,
          'author': author,
          'timestamp': Timestamp.now(),
        },
      );
      return true;
    } catch (e) {
      print(e);
      return false;
    }
  }

  Future<bool> deleteBook({required String docId}) async {
        try {

      return true;
    } catch (e) {
      print(e);
      return false;
    }
  }
}

Cloud Firestoreのデータを削除するには、collectiondocを指定し、deleteを設定します。

docの中にdocIdを指定します。

docIdは、削除ボタンを押した時に、docIdの値を受け取るようにします。

Future<bool> deleteBook({required String docId}) async {
  try {
    await _database.collection('books').doc(docId).delete();
    return true;
  } catch (e) {
    print(e);
    return false;
  }
}

home.dartのbooksリストには、docIdが入っていないので、doc.data()のオブジェクトにdocIdを追加します。

child: StreamBuilder(
  stream: _firebaseService!.getBooks(),
  builder: (BuildContext context, AsyncSnapshot snapshot) {
    if (snapshot.hasData) {
      final List books = snapshot.data!.docs.map((doc) {
        Map value = doc.data();
        value['docId'] = doc.id;
        return value;
      }).toList();

削除ボタンの動作を設定するために、_deleteを作成します。

_fiebaseServicedeleteBookを指定します。

deleteBookには、docIdを指定しましょう。

class _HomeState extends State<Home> {
  FirebaseService? _firebaseService;

  @override
  void initState() {
    super.initState();
    _firebaseService = GetIt.instance.get<FirebaseService>();
  }

  Future<void> _delete(dynamic docId) async {
    bool _result = await _firebaseService!.deleteBook(docId: docId);
    print('削除結果: $_result');
  }

削除ボタンを作成します。

onPressed_deleteを設定します。

_deleteには、bookdocIdを指定しましょう。

children: [
  Text(book['title'], style: TextStyle(fontSize: 24)),
  Text(book['author'], style: TextStyle(fontSize: 18)),
  MaterialButton(
    onPressed: () => _delete(book['docId']),
    color: Colors.redAccent,
    child: const Text(
      '削除',
      style: TextStyle(
          color: Colors.white, fontWeight: FontWeight.bold),
    ),
  )
],

一通り完成したので、動作確認しましょう。

image3

image4

削除ボタンをタップすると、

image5

削除ボタンをタップしたデータが削除されました。

image6

削除結果もtrueが返ってきていました。

念のため、FirebaseのCloud Firestoreも確認しましょう。

image7

こちらもデータが削除されていました。

次回は、Firebase Cloud Firestoreのデータを更新します。

ブログ一覧