본문 바로가기

Flutter/Firebase

[Firebase] Firebase usage example

One-time Read - get()

Collection 또는 document를 한번만 콜 하려면, Query.get or DocumentReference.get method를 사용하면 됩니다!


class GetUserName extends StatelessWidget {
  final String documentId;

  GetUserName(this.documentId);

  @override
  Widget build(BuildContext context) {
    CollectionReference users = FirebaseFirestore.instance.collection('users');

    return FutureBuilder<DocumentSnapshot>(
      future: users.doc(documentId).get(),
      builder:
          (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {

        if (snapshot.hasError) {
          return Text("Something went wrong");
        }

        if (snapshot.hasData && !snapshot.data!.exists) {
          return Text("Document does not exist");
        }

        if (snapshot.connectionState == ConnectionState.done) {
          Map<String, dynamic> data = snapshot.data!.data() as Map<String, dynamic>;
          return Text("Full Name: ${data['full_name']} ${data['last_name']}");
        }

        return Text("loading");
      },
    );
  }
}

 

여기서 FutureBuilder를 사용했는데

snapshot.data 가 futurebuilder로 받아온 데이터를 의미하고 

 

(여기서는 Data의 타입이 DocumentReference 일 것이다.)

 

고로 snapshot.data.data()은 DocumentSnapshot의 Document Data 전체를 가져올 수 있다.

 

이 때 Data를 as Map으로 해줘도 되고

받아오는 변수를 var로 선언해줘도 된다.

 

하지만 var 변수는 가독성이 떨어지기 때문에 Map<String,dynamic>으로 타입을 정하는 것을 권장한다.

 

 

Realtime changes - snapshot()

Both the CollectionReference & DocumentReference provide a snapshots() method which returns a Stream:

Realtime 변수는 Streambuilder 함수를 사용해서 가져올 수 있다.


Stream collectionStream = FirebaseFirestore.instance.collection('users').snapshots();
Stream documentStream = FirebaseFirestore.instance.collection('users').doc('ABC123').snapshots();

 

(Streambuilder 사용 예제)

 

class UserInformation extends StatefulWidget {
  @override
    _UserInformationState createState() => _UserInformationState();
}

class _UserInformationState extends State<UserInformation> {
  final Stream<QuerySnapshot> _usersStream = FirebaseFirestore.instance.collection('users').snapshots();

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<QuerySnapshot>(
      stream: _usersStream,
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (snapshot.hasError) {
          return Text('Something went wrong');
        }

        if (snapshot.connectionState == ConnectionState.waiting) {
          return Text("Loading");
        }

        return ListView(
          children: snapshot.data!.docs.map((DocumentSnapshot document) {
          Map<String, dynamic> data = document.data()! as Map<String, dynamic>;
            return ListTile(
              title: Text(data['full_name']),
              subtitle: Text(data['company']),
            );
          }).toList(),
        );
      },
    );
  }
}

 

여기서는 snapshot()으로 stream에 해당하는 Data를 가져왔으므로

Streambuilder를 사용해야한다.

 

snapshot.data.docs는 곧, List<Documentsnapshot>를 의미한다. 

 

여기서 forEachfromDocumentShapshot 함수를 잘 이용하면 model class를 객체화 시킬 때 유용하다.

 

+추가적으로 


Flutter State management 인 Bloc or Getx 등을 사용하면 사실 Stream을 쓸 일이 많지 않으니 get()을 잘 봐두자!