首页 > 解决方案 > 如何从firebase颤振中获取用户模型类中的数据

问题描述

我正在使用Firebase.

我的Users.dart文件:

  class Users{

  final String id;
  final String profileName;
  final String userName;
  final String url;
  final String email;
  final String bio;

  Users({
    this.id,
    this.profileName,
    this.userName,
    this.url,
    this.email,
    this.bio
  });

  factory Users.fromDocument(DocumentSnapshot doc){
    return Users(
        id: doc.data()['id'],
        email: doc.data()['email'],
        userName: doc.data()['userName'],
        url: doc.data()['url'],
        profileName: doc.data()['profileName'],
        bio: doc.data()['bio']
    );
  }
}

现在看Auth.dart文件:

import 'package:cloud_firestore/cloud_firestore.dart';
import  'package:firebase_auth/firebase_auth.dart' as auth;
import 'package:mms/models/User.dart';
import 'package:mms/screens/Homepage.dart';

class Auth{

  final auth.FirebaseAuth _auth = auth.FirebaseAuth.instance;
  final firebaseUser = auth.FirebaseAuth.instance.currentUser;

  Users _userFromFirebaseUser(auth.User user){
    return user != null ? Users(id: user.uid) : null;
  }

  Future login(String email, String password) async {
    try{
      auth.UserCredential result = await _auth.signInWithEmailAndPassword(email: email, password: password);
      auth.User user = result.user;
      return _userFromFirebaseUser(user);
    } catch(e){
      print(e.toString());
      return null;
    }
  }

  //signup and create user on Firebase
  Future register(String name, String email, String password) async {
    try{
      auth.UserCredential result = await _auth.createUserWithEmailAndPassword(email: email, password: password);
      auth.User user = result.user;
      return _userFromFirebaseUser(user);
    } catch(e){
      print(e.toString());
      return null;
    }
  }
  //signing out from the app
  Future signOut() async {
    try{
      return await _auth.signOut();
    } catch(e){
      print(e.toString());
      return null;
    }
  }
}

现在,当用户在我的应用程序上创建帐户到 Firestore 时,我正在保存数据,如下所示:

saveUserInfoToFirestore() async {
    var firebaseUser = auth.FirebaseAuth.instance.currentUser;
    DocumentSnapshot documentSnapshot =
        await firestoreInstance.collection('users').doc(firebaseUser.uid).get();

    if (!documentSnapshot.exists) {
      //final profileName = await Navigator.push(context, MaterialPageRoute(builder: (context) => SignupPage()));
      firestoreInstance.collection("users").doc(firebaseUser.uid).set({
        "uid": firebaseUser.uid,
        "profileName": _name,
        "email": firebaseUser.email,
        "timestamp": timestamp,
        "bio": ""
      }).then((_) => print('Success'));
      documentSnapshot = await firestoreInstance
          .collection('users')
          .doc(firebaseUser.uid)
          .get();
    }
    currentUser = Users.fromDocument(documentSnapshot); //currentUser is the instance of Users model class
  }
}

现在每当我打电话users.id时,我都会收到错误消息

The method '[]' was called on null.
Receiver: null
Tried calling: []("id")

users.id在我的以下调用了Search.dart

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:mms/models/Progress.dart';
import 'package:mms/models/User.dart';
import 'package:mms/screens/ActivityFeed.dart';
import 'package:mms/screens/Homepage.dart';

class SearchPage extends StatefulWidget {

  @override
  _SearchPageState createState() => _SearchPageState();
}

class _SearchPageState extends State<SearchPage> {
  TextEditingController searchTextEditingController = TextEditingController();
  Future<QuerySnapshot> futureSearchResults;
  String profileName;

  void initState(){
    super.initState();
    getProfileName();
  }
  clear() {
    searchTextEditingController.clear();
  }
  Future<void> getProfileName() async {
    final firestoreInstance = FirebaseFirestore.instance;
    firestoreInstance
        .collection("users")
        .doc(firebaseUser.uid)
        .get()
        .then((value) {
      setState(() {
        profileName = value.data()["profileName"].toString();
      });
    });
  }
  searchController(String str) {
    Future<QuerySnapshot> allUsers = FirebaseFirestore.instance
        .collection("users")
        .where("profileName", isGreaterThanOrEqualTo: str)
        .get();
    setState(() {
      futureSearchResults = allUsers;
    });
  }

  Container displayNoSearchResultScreen() {
    final Orientation orientation = MediaQuery.of(context).orientation;
    return Container(
      child: Center(
        child: ListView(
          shrinkWrap: true,
          children: <Widget>[
            Icon(
              Icons.group,
              color: Colors.grey,
              size: 200.0,
            ),
            Text(
              'Find Users',
              textAlign: TextAlign.center,
              style: TextStyle(
                  color: Colors.white,
                  fontWeight: FontWeight.w500,
                  fontSize: 50.0),
            )
          ],
        ),
      ),
    );
  }

  displayUsersFoundScreen() {
    return FutureBuilder(
        future: futureSearchResults, builder: (context, dataSnapshot) {
          if(!dataSnapshot.hasData){
            return circularProgress();
          }


          //This part is also not working properly
          List<UserResult> searchUserResult = [];
          dataSnapshot.data.docs.forEach((document){
            Users users = Users.fromDocument(document);
            UserResult userResult = UserResult(users);
            searchUserResult.add(userResult);
          });
          return ListView(children: searchUserResult,);
    });
  }

  AppBar searchPageHeader() {
    return AppBar(
      backgroundColor: Colors.black,
      title: TextFormField(
        style: TextStyle(fontSize: 18.0, color: Colors.white),
        controller: searchTextEditingController,
        decoration: InputDecoration(
            hintText: "Search",
            hintStyle: TextStyle(color: Colors.grey),
            enabledBorder: UnderlineInputBorder(
                borderSide: BorderSide(color: Colors.grey)),
            focusedBorder: UnderlineInputBorder(
                borderSide: BorderSide(color: Colors.white)),
            filled: true,
            prefixIcon: Icon(
              Icons.person_pin,
              color: Colors.white,
              size: 30.0,
            ),
            suffixIcon: IconButton(
              icon: Icon(
                Icons.clear,
                color: Colors.white,
              ),
              onPressed: clear,
            )),
        onFieldSubmitted: searchController,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      appBar: searchPageHeader(),
      body: futureSearchResults == null
          ? displayNoSearchResultScreen()
          : displayUsersFoundScreen(),
    );
  }
}

class UserResult extends StatelessWidget {

  final Users users;
  UserResult(this.users);

  @override
  Widget build(BuildContext context) {
    return Padding(
        padding: EdgeInsets.all(3.0),
      child: Container(
        color: Colors.white54,
        child: Column(
          children: <Widget>[
            GestureDetector(
              onTap: () => showProfile(context, profileId: users.id),//Here I have called but not working
              child: ListTile(
                //leading: CircleAvatar(backgroundColor: Colors.blue, backgroundImage: CachedNetworkImageProvider(users.url),),
                title: Text(users.profileName, style: TextStyle(
                  color: Colors.black, fontSize: 16.0, fontWeight: FontWeight.bold,
                ),),
             
              ),
            )
          ],
        ),
      ),
    );
  }
}

我找不到的错误是什么?如果有人能知道解决方案,请告诉我?

标签: firebaseflutterdartgoogle-cloud-firestorefirebase-authentication

解决方案


我发现的一个错误是您在以下内容中丢失awaitsearchController

 Future<void> searchController(String str) async {
    QuerySnapshot allUsers = await FirebaseFirestore.instance
        .collection("users")
        .where("profileName", isGreaterThanOrEqualTo: str)
        .get();
    setState(() {
      futureSearchResults = allUsers;
    });
  }

这里还有一个await问题:

saveUserInfoToFirestore() async {
    var firebaseUser = auth.FirebaseAuth.instance.currentUser;
    DocumentSnapshot documentSnapshot =
        await firestoreInstance.collection('users').doc(firebaseUser.uid).get();

    if (!documentSnapshot.exists) {
      //final profileName = await Navigator.push(context, MaterialPageRoute(builder: (context) => SignupPage()));
      await firestoreInstance.collection("users").doc(firebaseUser.uid).set({
        "id": firebaseUser.uid,
        "profileName": _name,
        "email": firebaseUser.email,
        "timestamp": timestamp,
        "bio": ""
      })
      documentSnapshot = await firestoreInstance
          .collection('users')
          .doc(firebaseUser.uid)
          .get();
    }
    currentUser = Users.fromDocument(documentSnapshot); //currentUser is the instance of Users model class
  }
}

如何使用它:


  displayUsersFoundScreen() {

          if(!futureSearchResults.hasData){
            return circularProgress();
          }


          //This part is also not working properly
          List<UserResult> searchUserResult = [];
          futureSearchResults.data.docs.forEach((document){
            Users users = Users.fromDocument(document);
            UserResult userResult = UserResult(users);
            searchUserResult.add(userResult);
          });
          return ListView(children: searchUserResult,);
    
  }

推荐阅读