空值上使用的空检查运算符:如何使用 Streams 和 firebase 数据库处理空安全?

时间:2021-06-20 18:17:42

标签: flutter dart

这是抛出错误的代码:

class BrewList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final brew = Provider.of<List<Brew>?>(context);

    return ListView.builder(
      itemCount: brew!.length,
      itemBuilder: (context, index) {
        return BrewTile(
          brew: brew[index],
        );
      },
    );
  }
}

还有一个错误:

======== Exception caught by provider ==============================================================
The following assertion was thrown:
An exception was throw by _MapStream<QuerySnapshot<Map<String, dynamic>>, List<Brew>?> listened by

StreamProvider<List<Brew>?>, but no `catchError` was provided.

Exception:
Bad state: field does not exist within the DocumentSnapshotPlatform

问题是我已经在 firestore 中设置了数据。我真的不知道该怎么处理这个错误

这是我的 auth.dart:

import 'package:brew_crew_app/models/user.dart';
import 'package:brew_crew_app/services/database.dart';
import 'package:firebase_auth/firebase_auth.dart';

class AuthService {
  final FirebaseAuth _auth = FirebaseAuth.instance;

  Userr? _userFromFirebaseUser(User? user) {
    if (user != null) {
      return Userr(useruid: user.uid);
    } else {
      return null;
    }
  }

  // here we are setting up the stream that every time the user signs in or signs out we are going to get a response .
  Stream<Userr?> get user {
    return _auth
        .authStateChanges()
        // .map((User? user) => _userFromFirebaseUSer(user));
        // here we have the same functionality here .
        .map(_userFromFirebaseUser);
  }

  Future signInAnon() async {
    try {
      final UserCredential userCredential = await _auth.signInAnonymously();
      // Exactly: The ? in User? indicates that the value may be null, so ensuring that user is defined resolves the issue .
      final user = userCredential.user;
      return _userFromFirebaseUser(user);
    } catch (e) {
      print(e.toString());
      return null;
    }
  }

  Future signOut() async {
    try {
      return await _auth.signOut();
    } catch (e) {
      print(e.toString());
      return null;
    }
  }

  Future signInUserWithEmailAndPassword(String email, String password) async {
    try {
      UserCredential userCredential = await _auth.signInWithEmailAndPassword(
          email: email, password: password);
      final user = userCredential.user;
      return _userFromFirebaseUser(user);
    } catch (e) {
      print(e.toString());
      return null;
    }
  }

  Future createUserWithEmailAndPassword(String email, String password) async {
    try {
      UserCredential userCredential = await _auth
          .createUserWithEmailAndPassword(email: email, password: password);
      final user = userCredential.user;
      // create a new document for the user with a unique uid.
      await DataBase(user!.uid).updateUserData('0', 'New Crew member', 100);
      return _userFromFirebaseUser(user);
    } catch (e) {
      print(e.toString());
      return null;
    }
  }

}

这是我的数据库:

class DataBase {
  DataBase(this.uid);

  final String uid;
  // collection refrence
  final CollectionReference brewCollection =
      FirebaseFirestore.instance.collection('brews');

  Future updateUserData(String sugars, String name, int strength) async {
    return await brewCollection.doc(uid).set({
      'sugers': sugars,
      'name': name,
      'strength': strength,
    });
  }

  // brew list from snapshot ...
  // this method is going to take a list of querySnapshot and here we have called it snapshot .
  List<Brew>? _brewListFromSnapshot(QuerySnapshot snapshot) {
    // here we want to cycle through the document of this snapshot by map method
    return snapshot.docs.map((doc) {
      // here we want to return a single brew for each doc that we are iterating through
      return Brew(
          name: doc.get('name') ?? '',
          strength: doc.get('strength') ?? 0,
          sugars: doc.get('sugars') ?? '0');
    }).toList();
  }

  // this document is going to notify us of any document changes that may happen in the data base is there any new document added ? come down to the stream and notify us . is there any document changes ? come down to the stream and notify us . every bit of data that we get down that stream is gonna be a  snapshot of that particular collection the brews collection of that moment in time that snapshot is basically is gonna be an object which contains the current document and their properties and values inside that collection ot that moment in time so then ist gonna be our job to get hte data we need from that snapshot and organize it in a way that we want on our app [so we are going to get up to date snapshot of the brews collection
  Stream<List<Brew>?> get brews {
    return brewCollection.snapshots().map(_brewListFromSnapshot);
  }

  // get user document stream
  Stream<UserData> get userData {
    return brewCollection.doc(uid).snapshots().map(_userDataFromSnapshot);
  }

  // here we need a method to take a document snapshot and turn it into  a user data object based on that user model
  // user data from snapshot
  UserData _userDataFromSnapshot(DocumentSnapshot snapshot) {
    return UserData(
      name: snapshot.get('name'),
      uid: uid,
      sugars: snapshot.get('sugars'),
      strength: snapshot.get('strength'),
    );
  }
}

我的 main.dart 文件:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider<ToggleView>(create: (_) => ToggleView()),
        ChangeNotifierProvider<LoadingIndicator>(
            create: (_) => LoadingIndicator()),
      ],
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return StreamProvider<Userr?>.value(
      value: AuthService().user,
      initialData: Userr(useruid: 'No user found'),
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        home: Wrapper(),
      ),
    );
  }
}

我对 Flutter 的主要问题是 Nullsafety,我的教程中没有涵盖 nullSafety,我很难在整个应用程序中跟踪它。请提供一些指导方针或教程,以便在我的应用中深入使用它。

0 个答案:

没有答案