StreamController для управления аутентификацией Firebase - PullRequest
0 голосов
/ 28 марта 2020

У меня проблемы со следующим потоком входа в Firebase. Я создал StreamController для прослушивания в первую очередь прослушивания потока OnAuthStateChanged из Firebase и добавил точку данных в этот поток (объект User с дополнительными данными, которые я получил из Firestore). Мое место было бы слушать этот поток StreamController в другом месте в моем приложении, чтобы получить полную информацию пользователя.

Мой класс AuthService:

import 'dart:async';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:dispatch/models/user.dart';
import 'package:firebase_auth/firebase_auth.dart';

class AuthService {
  static FirebaseAuth _auth = FirebaseAuth.instance;
  static Firestore _dbReference = Firestore.instance;
  final authStreamController = setStreamController();

  // create User, we will need to fetch more information from Firestore in the future
  Future<User> _userFromFirebaseUser(FirebaseUser user) async {
    //return user != null ? User(uid:user.uid) : null;
    return user != null ? (await _getUserDetailsAsync(User(uid:user.uid))) : null;
  }

  // get user details data
  Future<User> _getUserDetailsAsync(User user) async {
    try {
      QuerySnapshot querySnapshot = await _dbReference.collection('user-details')
        .where('auth_id', isEqualTo: user.uid)
        .getDocuments();
      Map<String, dynamic> userInfo = querySnapshot.documents.first.data;
      user.email = userInfo['email'] != null ? userInfo['email'] : null;
      user.firstName = userInfo['first_name'] != null ? userInfo['first_name'] : null;
      user.lastName = userInfo['last_name'] != null ? userInfo['last_name'] : null;
      return user;
    } catch(e) {
      print(e.toString());
      return null;
    }
  }

  // define a stream controller with the OnAuthStateChanged stream as its stream
  static StreamController<User> setStreamController(){
    StreamController<User> authStreamController = StreamController();
    Stream<User> _stream = _auth.onAuthStateChanged.map((FirebaseUser user) => User(uid: user.uid));
    authStreamController.addStream(_stream);
    return authStreamController;
  }

  // expose stream controller via a getter
  StreamController<User> get streamControllerGetter {
    return authStreamController;
  }

  // sign with email and password
  Future signInWithUserAndPassword(String email, String password) async {
    try {
      AuthResult result = await _auth.signInWithEmailAndPassword(email: email, password: password);
      FirebaseUser user = result.user;
      // fetch the user's details from Cloud Firestore
      // return final user
      User appUser = await _userFromFirebaseUser(user);
      authStreamController.sink.add(appUser);
      return appUser;
    } catch(e) {
      print(e.toString());
      return null;
    }
  }

  // sign out
  Future signOut() async {
    try {
      return await _auth.signOut();
    } catch(e) {
      print('Sign out failed:');
      print(e.toString());
      return null;
    }
  } 
}

Класс MyApp

class MyApp extends StatelessWidget {
    // wrap MaterialApp widget with Provider
    return StreamProvider<User>.value(
          //listening to the user change stream
          value: AuthService().streamControllerGetter.stream,
          child: MaterialApp(
            title: 'Flutter Demo',
            theme: ThemeData(
              primarySwatch: Colors.blue,
            ),
            home: LoginWrapper(),
          ),
    );
  }

По какой-то причине все это не работает, я, кажется, не получаю последний объект User, который я добавил в приемник StreamController. Есть идеи?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...