flutter에서 firestore사용하기(2)

Namkyu Park
Flutter Seoul
Published in
11 min readNov 19, 2019

firestore 에서 데이터 관리하기

들어가며

이전 포스트에서는 flutter프로젝트와 Firestore를 연동하는 방법에 대하여 알려드렸습니다. 이번 포스트에서는 Firestore가 데이터를 저장하는 방식과 더불어 flutter 코드를 통해 Firestore 에 저장된 데이터를 관리하는 방법에 대해 알아보겠습니다.

목차

Firestore 데이터 구조

다음은 Firestore의 데이터 구조를 비유한 그림입니다.

Firestore는 다른 SQL 데이터베이스와는 다르게 테이블 구조가 아닙니다. Firestore는 collection 안에 document들을 저장하고 document 안에 데이터를 저장하는 방식입니다.

각각의 document들은 key-value 구조로 데이터를 저장합니다. 모든 document는 collection 안에 속해있어야 하며 document 안에 subcollection을 저장할 수 있습니다. document 안에 저장되는 데이터는 다양한 자료형이 가능합니다. 다음 예시를 보겠습니다.

books라는 collection 안에 두개의 document가 있습니다. on_intelligence라는 id를 가진 document 안에는 세개의 field가 있습니다. 각 데이터는 Map<String, dynamic>형식으로 저장되어 있고, 각각 자료형이 number, boolean, String 입니다. 이제 본격적으로 flutter 프로젝트에서 데이터를 관리하는 방법에 대해 알려드리겠습니다.

Firestore에서 데이터 관리하기

모든 데이터베이스의 핵심은 CRUD입니다. 즉 데이터를 추가(Create)하고, 데이터를 읽고(Read), 데이터를 갱신(Update)하고, 데이터를 삭제(Delete)할 수 있다면 그 데이터베이스를 사용할 줄 안다고 말해도 무방합니다. 여기에 추가하여 특정 조건에 맞는 데이터를 읽는 query에 대해서도 알아보겠습니다. 설명에 앞서 main.dart를 아래와 같이 변경해주세요

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Firestore firestore = Firestore.instance;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("hello world"),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
FlatButton(
color: Colors.blue,
child: Text("create button",style: TextStyle(color : Colors.white)),
onPressed: (){
//클릭시 데이터를 추가해준다.
},
),
FlatButton(
color: Colors.blue,
child: Text("read button", style: TextStyle(color : Colors.white)),
onPressed: (){
//클릭시 데이터를 읽어준다
},
),
FlatButton(
color: Colors.blue,
child: Text("update button", style: TextStyle(color : Colors.white)),
onPressed: (){
//클릭시 데이터를 갱신해준다.
},
),
FlatButton(
color: Colors.blue,
child: Text("delete button", style: TextStyle(color : Colors.white)),
onPressed: (){
//클릭시 데이터를 삭제해 준다.
},
),
],
),
),
);
}
}

Firestore의 collection은 CollectionReference class이고, document는 DocumentReference class입니다. 클래스의 속성과 메서드를 참고하면, 데이터를 관리하기 수월해집니다.

Firestore에 관한 문서는 여기 에 있습니다.

데이터 추가하기

다양한 방법이 있지만 가장 활용하기 좋은 방법으로 설명하겠습니다. 우선, 첫번째 FlatButton을 다음과 같이 수정해주세요

FlatButton(
color: Colors.blue,
child: Text("create button", style: TextStyle(color : Colors.white)),
onPressed: (){
String book = "천년의_질문";
firestore.collection('books').document(book)
.setData({ 'page': 433, 'purchase?': false, 'title':'천년의_질문'});
},
),

document(DocumentReference class)의 setData메서드를 통해 간단하게 데이터를 추가할 수 있습니다. 해당 메서드의 매개변수는 map형 변수입니다. key-value 형식으로 데이터를 지정해주면 됩니다. 다음과 같이 코드를 작성하고 다시 실행하여 첫번째 버튼을 누르면 아래와 같은 결과가 나옵니다.

데이터 읽기

특정 데이터를 읽어 콘솔창에 해당 데이터를 출력해보겠습니다. 우선 두번째 FlatButton을 아래와 같이 수정해주세요

FlatButton(
color: Colors.blue,
child: Text("read button", style: TextStyle(color : Colors.white)),
onPressed: (){
String title = "";
firestore.collection("books").document("on_intelligence").get() .then((DocumentSnapshot ds){
title = ds.data["title"];
print(title);
});
},
),

“books” 라는 collection 안에 “on_intelligence”라는 document 안에 “title” 이라는 키를 가지고 있는 value값을 찾고 싶다고 가정하겠습니다. document(DocumentReference class)의 get 메서드는Future<DocumentSnapshot>을 반환합니다. 따라서 then메서드를 통해 반환된 자료형이 DocumentSnapshot이 될 때까지 기다립니다. 결과로 나온 ds는 DocumentSnapshot 클래스로 data 속성은 해당 document의 field들을 map형 자료형으로 저장합니다. 따라서 key값을 “title”로 설정하면 value 는 on_intelligence가 나올 것이며, 재 실행후 두번째 버튼을 누르면 콘솔창의 결과는 다음과 같습니다.

이렇게 데이터를 document단위로 읽기도 하지만, Stream클래스를 이용하여 데이터를 읽기도 합니다. 이에 대해서는 세번째 포스트에서 다루겠습니다.

데이터 갱신하기

데이터 갱신은 비교적 간단합니다. 세번째 FlatButton을 다음과 같이 수정해주세요

FlatButton(
color: Colors.blue,
child: Text("update button", style: TextStyle(color : Colors.white)),
onPressed: (){
firestore.collection("books").document("chemistry_between_us").updateData({"page":543});
},
),

chemistry_between_us라는 document의 page가 543로 수정하고 싶다고 가정하고 데이터를 갱신해보겠습니다. document(DocumentReference class)의 updateData 메서드를 이용하면 됩니다. 매개변수는 map형 자료형입니다. 재실행 하면 다음과 같은 결과가 나옵니다.

데이터 삭제하기

마지막으로 데이터를 삭제하는 방법입니다. document전체를 삭제하는 방법과 특정 field 하나를 삭제하는 방법을 소개시켜드리겠습니다. 네번째 FlatButton을 다음과 같이 수정해주세요

FlatButton(
color: Colors.blue,
child: Text("delete button", style: TextStyle(color : Colors.white)),
onPressed: (){
//특정 document 삭제
firestore.collection("books").document("천년의_질문").delete();
//특정 document 의 field 하나를 삭제
firestore.collection('books').document('chemistry_between_us').updateData({'page': FieldValue.delete()});
},
),

이 역시 document(DocumentReference class)의 메서드를 이용하면 됩니다. 실행시 다음과 같이 ‘천년의_질문’이라는 id를 가진 document 전체와 ‘chemistry_between_us’라는 id를 가진 document의 ‘page’ field가 사라진 것을 확인할 수 있습니다.

query 이용하기

특정 조건에 맞는 데이터를 수집하기 위해선 query를 사용합니다. 아래 코드와 같이 사용하며, Stream 클래스를 이용해야 하기 때문에 다음 포스트에서 다루겠습니다.

var data = await firestore.collection("books").where("purchase?",isEqualTo: true).snapshots().first;
String author = data.documents[0].data["title"];print(author);

마치며

이번 포스트에서는 flutter 프로젝트에서 firestore 데이터를 다루는 방법에 대하여 이야기 하였습니다. firestore가 이제 친숙해지셨나요? 다음 포스트에서는 지금까지 배운 내용들을 바탕으로 간단한 애플리케이션을 만들어보겠습니다.

--

--