在 null 上调用了 getter 'data'。接收者:空尝试调用:数据

时间:2021-03-29 11:55:34

标签: firebase flutter google-cloud-firestore materialpageroute

尝试使用 Firebase 注册用户,但出现上述错误,并且代码的格式设置为在成功注册后应将用户重定向到主页。

我的 main.dart

import 'package:bedc_app/home_page.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:bedc_app/auth/login_page.dart';

void main() async{
  //solution study

  WidgetsFlutterBinding.ensureInitialized();
  FirebaseAuth.instance.currentUser()
  .then((FirebaseUser user) {
    if(user != null){
      Firestore.instance.collection('users').document(user.uid).get().then((DocumentSnapshot doc){
        runApp(MyApp(true, doc));
      });
      return;
    }

    runApp(MyApp(false, null));
  });

}


// void main() =>runApp(MyApp());


class MyApp extends StatelessWidget {
  bool isLoggedIn;
  DocumentSnapshot doc;

  MyApp(this.isLoggedIn, this.doc);


  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My Multifunctional bedc project App',
      debugShowCheckedModeBanner: false,
      home: isLoggedIn ? HomePage(userDoc: doc) : loginPage(),
    );
  }
}

我的 Signup_page.dart

    import 'package:bedc_app/auth/login_page.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

import 'package:bedc_app/utils/constants.dart';

import '../home_page.dart';


class SignUpPage extends StatefulWidget {
  @override
  _SignUpPageState createState() => _SignUpPageState();
}

class _SignUpPageState extends State<SignUpPage> {

  String email, password;

  bool isLoggedIn = false;


  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Colors.white,
        body: ListView(
                children: [
                  SizedBox(
                    height: 50,
                  ),

                  Align(
                    alignment: Alignment.topCenter,
                    child: (
                    Image.asset(
                      'assets/bedclogo.jpg'
                    )),
                  ),

                  SizedBox(
                    height: 100,
                  ),

                  Padding(
                      padding: EdgeInsets.symmetric(horizontal: 26.0),
                      child: TextField(
                        decoration: InputDecoration(
                          hintText: 'email',
                          border: OutlineInputBorder(),
                          labelText: 'Email',
                          suffixIcon: Icon(Icons.email, color: Colors.green)
                        ),
                        keyboardType: TextInputType.emailAddress,
                        onChanged: (String val){
                          email = val;
                        },


                      ),
                        ),

                  SizedBox(
                    height: 10,
                  ),


                  Padding(
                    padding: EdgeInsets.symmetric(horizontal: 26.0),
                    child: TextField(
                      decoration: InputDecoration(
                          hintText: 'Password',
                          border: OutlineInputBorder(),
                          labelText: 'Password',
                          suffixIcon: Icon(Icons.lock, color: Colors.green)
                      ),
                      obscureText: true,
                      obscuringCharacter: '!',
                      keyboardType: TextInputType.emailAddress,
                      onChanged: (String val){
                        password = val;
                      },
                    ),),


                  SizedBox(
                    height: 5,
                  ),
                  Padding(
                    padding: EdgeInsets.symmetric(horizontal: 26),
                    child: MaterialButton(
                      color: Color(0xFF88C540),
                      child: isLoading ? Container(
                          height: 24,
                          width: 24,
                          child: CircularProgressIndicator(
                            valueColor: AlwaysStoppedAnimation<Color>(Colors.black),
                            strokeWidth: 2,
                          )
                      ):Text(
                        'SignUp'.toUpperCase(),
                        style: TextStyle(fontWeight: FontWeight.bold),
                      ),
                      onPressed: (){
                          checkUserInput();
                      },
                    ),
                  ),


                  SizedBox(
                    height: 10,
                  ),
                  Padding(
                    padding: EdgeInsets.symmetric(horizontal: 20),
                    child: RichText(
                        text: TextSpan(
                            text: 'Already have an Account ?',
                            style: TextStyle(color: Colors.black),
                            children: [
                              TextSpan(
                                text: 'Login here',
                                style: TextStyle(color: Colors.blue),
                                recognizer: TapGestureRecognizer()..onTap = (){
                                  Navigator.of(context).pushReplacement(CupertinoPageRoute(builder: (_) => loginPage()));
                                },
                              )
                            ]
                        )),
                  )
                ],

    ));
  }

  //SIGNUP FUNCTION USING FIREBASE
  bool isLoading = false;
  signUpUserWithFirebase(){
    FirebaseAuth.instance.createUserWithEmailAndPassword(
        email: email,
        password: password
    ).then((AuthResult result){

      //Authresult cant be stored to string.....
      storeUserDataToFirestore(result.user.uid);
      if(result.user.uid != null){
        Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (_) => HomePage()));
      }
    }).catchError((e){
      print(e);
      isLoading = false;
      setState(() { });

    });
  }

  //storeUserDataToFirestore
  storeUserDataToFirestore(String userId){
            Map<String, dynamic> userData = Map<String, dynamic>();

            userData = {
              Constants.USERNAME: '@username',
              Constants.USER_ID: userId,
              Constants.EMAIL : email,
              Constants.ACCOUNT_NUM : '00000000',
              Constants.IS_ADMIN: false,
              Constants.PROFILE_IMAGE: '',
              Constants.PROFILE_IMAGE_THUMB: '',
            };

          CollectionReference usersRef = Firestore.instance.collection(Constants.USERS_COLLECTION);
          usersRef.document(userId).setData(userData).then((_){
            isLoading = false;
            setState(() { });
          }).catchError((e){
            print(e);
          });
  }
//FUNCTION TO CHECK USER ENTRY
  checkUserInput(){
      isLoading = true;
      setState(() { });

      if(email == null || email.isEmpty){
        print('Enter email');
        isLoading = false;
        setState(() { });
        return;
      }

      if(password == null || email.isEmpty){
        print('Enter password');
        isLoading = false;
        setState(() { });
      }

      //SIGNUP THE USER
        signUpUserWithFirebase();
  }

  getUserData(String UserId){
    Firestore.instance.collection(Constants.USERS_COLLECTION)
        .document(UserId)
        .get().then((DocumentSnapshot userDoc){
        Navigator.of(context).pop();
        Navigator.of(context).pushReplacement(CupertinoPageRoute(builder: (_) => HomePage(userDoc: userDoc)));
    }).catchError((e){
        print(e);
    });

  }

}

我的主页_page.dart

import 'dart:ui';

import 'package:bedc_app/auth/login_page.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:bedc_app/auth/signup_page.dart';

import 'model/user.dart';


User currentUser;
class HomePage extends StatefulWidget {

  DocumentSnapshot userDoc;

  HomePage({this.userDoc,});

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

class _HomePageState extends State<HomePage> {

//user cant access this page unless logged in

  bool userIsLoggedIn = true;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    currentUser = User.fromSnapshot(widget.userDoc);
  }
//HERE IS BUILDING PROFILE IMAGE
  Widget buildProfileImage(){
      if(currentUser.profileImage == ''){
        return CircleAvatar(
          backgroundColor: Colors.white70,
          radius: 20,
          child: Icon(Icons.person, size: 30),
        );
      }else{
        return CircleAvatar(
              backgroundImage: NetworkImage(currentUser.profileImage),
        );
      }
  }

    Widget build(BuildContext context) {
      return Scaffold(
          appBar: AppBar(
            automaticallyImplyLeading: false,
            backgroundColor: Colors.brown,
            title: Text('Homepage'),

          ),
          body: ListView(
            children: [
                 SizedBox(height: 20),

              Align(
                alignment: Alignment.topRight,
                child: (
                    Image.asset(
                        'assets/bedclogo.jpg',
                      scale: 2,
                    )),
              ),


              ListTile(
                title: Text(currentUser.username, style: TextStyle(color: Colors.brown, fontWeight: FontWeight.bold),),
                leading: buildProfileImage(),
              ),

              SizedBox(height: 30),

            //CAPTURE METER READING UI
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 20.0),
                child: GestureDetector(
                  onTap: (){
                    //print(currentUser.isAdmin);
                  },
                  child: Row(
                    children: [

                      //CAPTURE METR READING
                      Container(
                        width: 100,
                        height: 100,
                        color: Colors.green,
                              child: Align(
                                    alignment: Alignment.center,
                                    child: (
                                        Image.asset(
                                          'assets/meterIcon.png',
                                          scale: 3,
                                        )),
                              ),
                      ),

                      Container(
                        width: 100,
                        height: 100,
                        child: Align(
                          alignment: Alignment.center,
                          child: Text('Capture Meter Reading'.toUpperCase()),
                        ),
                      ),

                    ],
                  ),
                ),
              ),

              SizedBox(height: 30),

              //UPDATE PROFILE UI DESIGN

              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 20.0),
                child: GestureDetector(
                  onTap:(){
                    //print(currentUser.isAdmin);
                  },
                  child: Row(
                    children: [


                      Container(
                        width: 100,
                        height: 100,
                        color: Colors.green,
                        child: Align(
                          alignment: Alignment.center,
                          child: (
                              Image.asset(
                                'assets/profileAvatar.png',
                                scale: 3,
                              )),
                        ),
                      ),

                      Container(
                        width: 100,
                        height: 100,
                        child: Align(
                          alignment: Alignment.center,
                          child: Text('Update Profile'.toUpperCase()),
                        ),
                      ),

                    ],
                  ),
                ),
              ),

//               TextButton (
//                   onPressed: (){
//                     //just logout, implement pop dialog later
//                     // FirebaseAuth.instance.signOut();
//                     // Navigator.of(context).pushReplacement(CupertinoPageRoute(builder: (_)=> loginPage()));
//                     // currentUser = null;
//                     // setState(() {
//                     // });
// // still showing error... try to fix asap
//                     FirebaseAuth.instance.signOut().then((_){
//                       userIsLoggedIn = false;
//                       Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (_)=> loginPage()));
//                       //currentUser = null;
//                       setState(() {
//
//                       });
//                     });
//                   },
//                   child: Text('SignOut'))

            ],

          )
      );
    }
  }

用户模型的 User.dart

import 'package:bedc_app/utils/constants.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

class User{
String username;
String email;
String userId;
String accountNum;
bool isAdmin;
String profileImage;
String profileImageThumb;

User({
  this.username,
  this.email,
  this.userId,
  this.accountNum,
  this.isAdmin,
  this.profileImage,
  this.profileImageThumb
});

factory User.fromSnapshot(DocumentSnapshot doc){

  return User(
      username: doc.data[Constants.USERNAME],
      email: doc.data[Constants.EMAIL],
      userId: doc.data[Constants.USER_ID],
      accountNum: doc.data[Constants.ACCOUNT_NUM],
      isAdmin: doc.data[Constants.IS_ADMIN],
      profileImage: doc.data[Constants.PROFILE_IMAGE],
      profileImageThumb: doc.data[Constants.PROFILE_IMAGE_THUMB]
  );
}

}

在用户注册后,我收到错误 getter 'data' 被调用为 null。接收者:空尝试调用:数据。

我不知道是代码的哪一部分导致了这个异常

1 个答案:

答案 0 :(得分:1)

当您尝试获取空对象的某些属性时,通常会出现此错误

在您的情况下,调用文件 User.dart 中的 doc.data[..] 之一会生成错误,这意味着 { {1}} 是真的。

在 Home_page.dart 文件的 initState 方法

上验证此行 doc == null 处的 widget.userDoc 不为空

因此,在需要非空 userDoc 的 HomePage 调用之一中提供错误(待办事项:使用断言确保您的数据不为空,并在类 exp 上的必需变量之前添加 currentUser = User.fromSnapshot(widget.userDoc);:{{1 }} 在您调试应用程序时非常有用)

最终您的问题在您的 Signup_page.dart 文件的 @required 方法中提供...这里HomePage({@required this.userDoc,}): assert(userDoc != null, "BOooh my userDoc may be not null");

尝试用这个 signUpUserWithFirebase() 替换,这样你的方法应该变成

Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (_) => HomePage()));