home: StreamBuilder(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (ctx, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
}
if (snapshot.hasData) {
return const ChatScreen();
}
return const AuthScreen();
},
),
child: FutureBuilder(
future: _placesFutre,
builder: (context, snapshot) =>
snapshot.connectionState == ConnectionState.waiting
? const Center(child: CircularProgressIndicator())
: PlacesList(places: userPlaces),
),
각각 stream, future에 의존되는 값에 의해서 build하는 위젯이 바뀐다는 것이다. 그럼 두 Builder 메서드의 차이점은 무엇일까? => 바로 FutureBuilder는 단 1개의 값 || error 요렇게 true, false 성격을 갖지만 StreamBuilder의 경우는 굉장히 다양한 값을 갖을 수 있다는 점이 바로 차이점이다.
하지만 공통점으로는 2번째 인수로 받는 함수의 2번째 인수인 snapshot에 첫번째 인수인 의존성에 대한 현재 상태값이 들어있다는 것이 공통점이다. 즉, 현재 상태값이 담겨있는 snapshot 코드를 이용하여 UI를 업데이트할 수 있다.
또한 두 Builder 모두 snapshot에 connectionState 속성이 있는데 이를 꼭 활용하여 로딩중에 auth가 되기 전 화면이 잠깐 깜빡이고 지가가는, 의도되지 않은 모습이 나오지 않도록 로딩 스피너나 loading...
이 담겨있는 screen을 만들어 좀 더 나은 UX를 줄 수 있도록 하자.
그래서 firebase에 보면 authStateChanges 메서드는 Stream 값을 반환하는데 이는 Firebase에서 관리하고 auth 값이 변한다면 Firebase 차원에서 업데이트 해준다.
그리고 만약 당신이 app을 껐다가 켜도 따로 로직을 구현하지 않았다면 지속해서 로그인상태가 되어있을 텐데 그것이 모두 firebase SDK에서 관리를 하고 저장도 하기 때문이다.
그 뜻은 singOut 메서드를 어떠한 icon에 맞춰서 구현하였다면 해당 FirebaseAuth 객체가 해당 이벤트를 listen하여 즉시 UI를 업데이트해준다는 것이다.