虎視眈々と

Flutter × Firebaseを研究するアプリエンジニア

FlutterでローカルDBにデータを保存する

f:id:superman199323:20181104164314j:plain

FlutterでローカルDBにデータを保存する

メッセージがきたときに未読数を画面に表示したかったのでローカルDBを使った。

www.shogogeek.com

プラグインを導入する

pub.dartlang.org

コード

DBHelperを作る

import 'dart:async';
import 'dart:io';

import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';

class DbHelper {
  static Database _db;

  static Future<Database> get db async {
    if (_db != null) return _db;
    _db = await _initDb();
    return _db;
  }

  static _initDb() async {
    Directory documentDirectory = await getApplicationDocumentsDirectory();
    String path = join(documentDirectory.path, "group_album.db");
    var db = await openDatabase(path, version: 1, onCreate: _onCreate);
    return db;
  }

  static _onCreate(Database db, int version) async {
    await db.execute(
        "CREATE TABLE messages(messageId TEXT PRIMARY KEY, userId TEXT, groupId TEXT, message TEXT, createdAt TEXT)"
    );
  }
}

保存、更新、削除

基本的に使い方は全て同い。

rawInsert の部分は更新、削除の場合は別のものを使う。 あとは、いつも通りSQLを使えばいいだけ。

Future<void> saveMessage(Message message, String messageId) async {
    // 差分だけ保存する
    List<Message> messageList = await _getMessages(messageId);
    if (messageList.length == 0) {
      var db = await DbHelper.db;
      await db.transaction((txn) async {
        await txn.rawInsert(
            'INSERT INTO messages(messageId, userId, groupId, message, createdAt) VALUES(' +
                '\'' +
                message.messageId +
                '\'' +
                "," +
                '\'' +
                message.userId +
                '\'' +
                "," +
                '\'' +
                message.groupId +
                '\'' +
                "," +
                '\'' +
                message.message +
                '\'' +
                "," +
                '\'' +
                message.createdAt +
                '\'' +
                ')');
      });
    }
  }

取得

取得する場合は、特にSQLも書かなくても大丈夫

Future<List<Message>> _getMessages(String messageId) async {
    var dbClient = await DbHelper.db;
    List<Map> list = await dbClient.rawQuery(
        'SELECT * FROM messages where messageId = ' + '\'$messageId\'');
    List<Message> messages = new List();
    for (int i = 0; i < list.length; i++) {
      messages.add(new Message(list[i]["messageId"], list[i]["userId"],
          list[i]["groupId"], list[i]["message"], list[i]["createdAt"]));
    }
    print(messages.length);
    return messages;
  }

総括

これだけでiOSもAndroidも両方ローカルDBが作れてしまうので本当にすごい。