Firestore

概要

Firestoreとは、Firebaseの機能の一つでNoSQLを提供している。

Quote

Google Cloud インフラストラクチャ上に構築された柔軟でスケーラブルな NoSQL クラウド データベースを使用して、クライアントサイドおよびサーバーサイド開発用のデータを保存および同期します。
Cloud Firestore は、Firebase と Google Cloud からのモバイル、ウェブ、サーバー開発に対応した、柔軟でスケーラブルなデータベースです。
Firebase Realtime Database と同様に、リアルタイム リスナーを介してクライアント アプリ間でデータを同期し、モバイルとウェブのオフライン サポートを提供します。
これにより、ネットワーク レイテンシやインターネット接続に関係なく機能するレスポンシブ アプリを構築できます。
Cloud Firestore は、その他の Firebase および Google Cloud プロダクト(Cloud Functions など)とのシームレスな統合も実現します。

使用方法

Web側

まず、FirebaseWebサイトからプロジェクトに移動して、左メニューバーの構築をクリックして、Firestoreをクリックする。

このような画面になる。

ソースコード側

導入

pubspec.yamlに依存関係を記入する。

cloud_firestore | Flutter Package (pub.dev)

cloud_firestore: ^4.13.4

そしてインポートする。

import 'package:cloud_firestore/cloud_firestore.dart';

コード前提知識

collection

collectionというのは、SQLでいうテーブルとほぼ同義である。

doc

docというのは、各レコードごとの一意な値を設定する。
基本的にはdocからレコードを検索する。

使用可能なデータ型
  • int
  • String
  • Array
  • bool
  • Bytes
  • Timestamp
  • float
  • Geographical Coodinates(duplicate)(地理的座標)
  • Map
  • Reference
このノートにおける例

このノートでは、以下のコードによりカラムを定義する。
基本的にFirestoreのレコード追加などはMap型で行うことができる。
その時の型は、Map<String, dynamic>Map<カラム名, 挿入したい値>である。

class Users{
	late final String _userId;
	late final String _name;
	late final String _birthday;
	late final String _iconImageLocalPath;
	late final String _email;
	
	late final Map<String, dynamic> _dbProcessedMap;
	
	String get userId => _userId;
	Map<String, dynamic> get dbProcessedMap => _dbProcessedMap;
	
	Users({
		required String nameArg,
		required String birthdayArg,
		required String iconLocalPathArg,
		required String emailArg
	}){
		_userId = emailArg;
		_name = nameArg;
		_birthday = birthdayArg;
		_iconImageLocalPath = iconLocalPathArg;
		_email = emailArg;
	
		_dbProcessedMap = {
			UsersTableColumn.NAME.name: _name,
			UsersTableColumn.BIRTHDAY.name:_birthday,
			UsersTableColumn.ICON_Image_LOCAL_PATH.name:_iconImageLocalPath,
			UsersTableColumn.EMAIL.name: _email
		};
	}
}
 
enum UsersTableColumn{
	NAME,
	BIRTHDAY,
	ICON_Image_LOCAL_PATH,
	EMAIL
}

コード

例外処理は省いている。

書き込み

setを使用する。
これは上書きである。

const TABLE_NAME = "users";
 
Future add() async {
	await FirebaseFirestore.instance.
		.collection(TABLE_NAME)
		.doc(newUserDataArg.userId)
		.set(newUserDataArg.dbProcessedMap);
}
更新

updateを使用する。

Future update({required Users newUserDataArg, required UsersTableColumn columnArg}) async{
	await FirebaseFirestore.instance.
		.collection(TABLE_NAME)
		.doc(newUserDataArg.userId)
		.update(newUserDataArg.dbProcessedMap);
}
読み出し

getを使用する。
Mapデータを取得するときは、取得した変数[UsersTableColumn.カラム名(データベースの項目名).name]と記述する。

Future<Map<String, dynamic>> fetch({required String targetUserIdArg}) async{
	final fetchedUser = await FirebaseFirestore.instance.
		.collection(TABLE_NAME)
		.doc(targetUserIdArg)
		.get();
	
	return fetchedUser.data() ?? {};
}
検索

whereを使用する。
where句内には、クエリを記述する。
書き方としては、where(field, クエリパラメータ: 検索目標)である。

Future<Map<String, dynamic>> search({required String targetUserNameArg}) async{
	final searchedUser = await FirebaseFirestore.instance.
		.collection(TABLE_NAME)
		.where(UserTableColumn.NAME.name, isEqualTo: targetUserNameArg)
		.get();
	
	return searchededUser.data() ?? {};
}
引数動作
fieldドキュメント内のフィールド名を指定。
このフィールドに基づいてクエリが実行される。
isEqualToフィールドの値が等しいドキュメントを検索
isNotEqualToフィールドの値が等しくないドキュメントを検索
isLessThanフィールドの値が指定された値未満のドキュメントを検索
isLessThanOrEqualToフィールドの値が指定された値以下のドキュメントを検索
isGreaterThanフィールドの値が指定された値より大きいドキュメントを検索
isGreaterThanOrEqualToフィールドの値が指定された値以上のドキュメントを検索
arrayContainsフィールドが配列であり、その配列に指定された値が含まれているドキュメントを検索
arrayContainsAnyフィールドが配列であり、その配列に指定された値のいずれかが含まれているドキュメントを検索
whereInフィールドの値が指定された配列に含まれているドキュメントを検索
whereNotInフィールドの値が指定された配列に含まれていないドキュメントを検索
orderByクエリ結果を特定のフィールドでソート
descendingパラメータをtrueに設定すると降順、falseまたは省略時は昇順になる。

DateTimeとTimestamp

相互変換

Timestamp timestamp = Timestamp.fromDate( ... );
 
DateTime dateTime = timestamp.toDate();