본문 바로가기

PROGRAMING/FLUTTER

Flutter에서 Firebase에 Database를 사용해서 리스트를 표시하기.!![WEB]

https://github.com/Dart-for-Apps/firebase-for-flutter

라이브러리를 설치해야한다.
해당 문서를 보고 flutter를 웹에서 띄울려면 웹전용 라이브러리를 설치해야하는지 알았다.
아 영어 ㅠㅠ
디폴트 라이브러리에 웹까지 다 지원하는게 포함되어있다.

그러므로 쓰는곳에도 웹라이브러리를 임포트 하는게 아니라 그냥 라이브러리를 임포트 한다.

웹에서 할때 별도로 해주어야 할것은 

web/index.html 수정

이것 뿐이다.

firebase  database를 쓰기전 배열에 담은 코드

import 'package:firebase/firestore.dart';
import 'package:flutter/material.dart';

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

final dummySnapshot = [
 {"name": "Filip", "votes": 15},
 {"name": "Abraham", "votes": 14},
 {"name": "Richard", "votes": 11},
 {"name": "Ike", "votes": 10},
 {"name": "Justin", "votes": 1},
];

class MyApp extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     title: 'Baby Names',
     home: MyHomePage(),
   );
 }
}

class MyHomePage extends StatefulWidget {
 @override
 _MyHomePageState createState() {
   return _MyHomePageState();
 }
}

class _MyHomePageState extends State<MyHomePage> {
 @override
 Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(title: Text('Baby Name Votes')),
     body: _buildBody(context),
   );
 }

 Widget _buildBody(BuildContext context) {
   // TODO: get actual snapshot from Cloud Firestore
   return _buildList(context, dummySnapshot);
 }

 Widget _buildList(BuildContext context, List<Map> snapshot) {
   return ListView(
     padding: const EdgeInsets.only(top: 20.0),
     children: snapshot.map((data) => _buildListItem(context, data)).toList(),
   );
 }

 Widget _buildListItem(BuildContext context, Map data) {
   final record = Record.fromMap(data);

   return Padding(
     key: ValueKey(record.name),
     padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
     child: Container(
       decoration: BoxDecoration(
         border: Border.all(color: Colors.grey),
         borderRadius: BorderRadius.circular(5.0),
       ),
       child: ListTile(
         title: Text(record.name),
         trailing: Text(record.votes.toString()),
         onTap: () => print(record),
       ),
     ),
   );
 }
}

class Record {
 final String name;
 final int votes;
 final DocumentReference reference;

 Record.fromMap(Map<String, dynamic> map, {this.reference})
     : assert(map['name'] != null),
       assert(map['votes'] != null),
       name = map['name'],
       votes = map['votes'];

 Record.fromSnapshot(DocumentSnapshot snapshot)
     : this.fromMap(snapshot.data(), reference: snapshot.ref);

 @override
 String toString() => "Record<$name:$votes>";
}

/*https://github.com/Dart-for-Apps/firebase-for-flutter*/

firebase의 database를 써서 사용한 코드

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

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

final dummySnapshot = [
 {"name": "Filip", "votes": 15},
 {"name": "Abraham", "votes": 14},
 {"name": "Richard", "votes": 11},
 {"name": "Ike", "votes": 10},
 {"name": "Justin", "votes": 1},
];


class Record {
 final String name;
 final int votes;
 final DocumentReference reference;

 Record.fromMap(Map<String, dynamic> map, {this.reference})
     : assert(map['name'] != null),
       assert(map['votes'] != null),
       name = map['name'],
       votes = map['votes'];

 Record.fromSnapshot(DocumentSnapshot snapshot)
     : this.fromMap(snapshot.data, reference: snapshot.reference);


 @override
 String toString() => "Record<$name:$votes>";
}

class MyApp extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     title: 'Baby Names',
     home: MyHomePage(),
   );
 }
}

class MyHomePage extends StatefulWidget {
 @override
 _MyHomePageState createState() {
   return _MyHomePageState();
 }
}

class _MyHomePageState extends State<MyHomePage> {
 @override
 Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(title: Text('Baby Name Votes')),
     body: _buildBody(context),
   );
 }

Widget _buildBody(BuildContext context) {
    return StreamBuilder<QuerySnapshot>(
    stream: Firestore.instance.collection('baby').snapshots(),
   builder: (context, snapshot) {
     if (!snapshot.hasData) return LinearProgressIndicator();

     return _buildList(context, snapshot.data.documents);
   },
 );
}

 Widget _buildList(BuildContext context, List<DocumentSnapshot> snapshot) {
   return ListView(
     padding: const EdgeInsets.only(top: 20.0),
     children: snapshot.map((data) => _buildListItem(context, data)).toList(),
   );
 }



 
/*https://github.com/Dart-for-Apps/firebase-for-flutter*/

 Widget _buildListItem(BuildContext context, DocumentSnapshot data) {
 final record = Record.fromSnapshot(data); // 변경된 부붙 fromMap 을 fromSnapshot 으로
   return Padding(
     key: ValueKey(record.name),
     padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
     child: Container(
       decoration: BoxDecoration(
         border: Border.all(color: Colors.grey),
         borderRadius: BorderRadius.circular(5.0),
       ),
        child: ListTile(
          title: Text(record.name),
          trailing: Text(record.votes.toString()),
          //onTap: () => print(record),
         onTap: () => Firestore.instance.runTransaction((transaction) async {
            final freshSnapshot = await transaction.get(record.reference);
            final fresh = Record.fromSnapshot(freshSnapshot);
            await transaction.update(record.reference, {'votes': fresh.votes + 1});
          }),

       ),
     ),
   );
 }
}

/*https://github.com/Dart-for-Apps/firebase-for-flutter*/

firebase  database를 써서 자료를 가져오려면 firebas에 데이터를 넣어두어야한다.

자료가 넣어둔 화면은 위와 같고

표시되는 화면은 이것과 같다.

Test를 해보면서 firebase database의 데이터를 변경하면 웹하면이 바로바로 바뀌었다.
뭐지. web socket이 자동으로 들어가나 했는데
찾아보니 service worker 라는 새로운 웹 기술이었다.
별도의 프로세스가 웹 브라우저에서 돌면서 화면 제어권은 가지지 않고
여러 상태관리를 화면서 화면을 호출한다고 한다.

web socket하고는 다른 기술이고 테스트해보니 엣지 , 크롬에서는 동작하나 IE11에서는 동작하지 않았다
신기한 세상이다.

https://developers.google.com/web/fundamentals/primers/service-workers?hl=ko

 

서비스 워커: 소개  |  Web Fundamentals  |  Google Developers

풍부한 오프라인 경험, 주기적 백그라운드 동기화, 푸시 알림(일반적으로 기본 애플리케이션을 요구하는 기능)이 웹에서 지원되고 있습니다. 서비스 워커는 이러한 모든 기능의 기술적 기반을 제공합니다.

developers.google.com