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

今回は、Firebase のデータベースにデータを追加します。

前回、Firebase へ接続するために作成したコードは、こちらです。

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();
  }
}

コードについて、詳しくは過去の内容をご覧ください。

Cloud FIrestore へデータを追加するための関数を作成します。

名前は、postBookとしました。

また、titleは必須にし、authorは任意としました。

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/catchを作成します。

catchには、エラーメッセージを出力し、false を返すようにします

Future<bool> postBook({required String title, String? author}) async {
  try {

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

tryに、_databasecollectionを設定します。

collectionには、コレクション名である、『books』を指定しました。

データベースを作成するために add を設定します。

addの中に、titleauthortimestampを指定します。

Timestamp.now()にすることで、現在時刻を取得することができます。

成功した場合、true を返すようにします。

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;
  }
}

次に、書籍登録画面を作成します。

import 'package:flutter/material.dart';

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

  @override
  State<PostBook> createState() => _PostBookState();
}

class _PostBookState extends State<PostBook> {
  double? _deviceWidth, _deviceHeight;

  final GlobalKey<FormState> _postBookKey = GlobalKey<FormState>();

  String? _title;
  String? _author;

  void _post() async {
    _postBookKey.currentState!.save();

  }

  @override
  Widget build(BuildContext context) {
    _deviceWidth = MediaQuery.of(context).size.width;
    _deviceHeight = MediaQuery.of(context).size.height;

    return Scaffold(
      body: SafeArea(
        child: Container(
          padding: EdgeInsets.symmetric(
            horizontal: _deviceWidth! * 0.05,
          ),
          child: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              mainAxisSize: MainAxisSize.max,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                const Text(
                  '書籍登録',
                  style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
                ),
                Container(
                  height: _deviceHeight! * 0.2,
                  child: Form(
                    key: _postBookKey,
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.spaceAround,
                      mainAxisSize: MainAxisSize.max,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: [
                        TextFormField(
                          decoration: const InputDecoration(hintText: 'タイトル'),
                          onSaved: (_value) {
                            setState(() {
                              _title = _value;
                            });
                          },
                        ),
                        TextFormField(
                          decoration: const InputDecoration(hintText: '著者'),
                          onSaved: (_value) {
                            setState(() {
                              _author = _value;
                            });
                          },
                        ),
                      ],
                    ),
                  ),
                ),
                MaterialButton(
                  onPressed: _post,
                  minWidth: _deviceWidth! * 0.5,
                  height: _deviceHeight! * 0.06,
                  color: Colors.blueAccent,
                  child: const Text(
                    '登録',
                    style: TextStyle(
                        color: Colors.white, fontWeight: FontWeight.bold),
                  ),
                )
              ],
            ),
          ),
        ),
      ),
    );
  }
}

get_itと、先ほど作成したfirebase_service.dartをインポートします。

import 'package:get_it/get_it.dart';
import 'package:test_form/services/firebase_service.dart';

FirebaseService の変数を作成します。

class _RegisterState extends State<Register> {
  double? _deviceWidth, _deviceHeight;

  FirebaseService? _firebaseService;

initStateを作成し、GetItgetFirebaseServiceを呼び出します。

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

内容を Firebase に送信するために、_post_firebaseServicepostBookを設定します。

_resultを表示できるようにしておきましょう。

void _post() async {
  _postBookKey.currentState!.save();

  bool _result =
      await _firebaseService!.postBook(title: _title!, author: _author);
  print('認証結果: $_result');
}

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

フォームにタイトルと著者を入力します。

image2

登録ボタンをタップすると、

image3

認証結果:true が返ってきました。

Firebase の Cloud Firestore を確認しましょう。

image4

Flutter で送信したデータがドキュメントに追加されていました。

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

ブログ一覧