【问题标题】:Flutter: Unhandled Exception: NoSuchMethodError: The getter 'id' was called on null. Receiver: null Tried calling: idFlutter:未处理的异常:NoSuchMethodError:在 null 上调用了 getter 'id'。接收方:null 尝试调用:id
【发布时间】:2020-11-03 18:50:13
【问题描述】:

我在使用 Flutter 使用电子邮件和密码注册时遇到问题。我让它登录新用户并保存他们的 Firebase 身份验证信息,但它不会将任何配置文件数据保存到 Firebase 存储部分。我不确定我在这里做错了什么,我不明白为什么 id 为空。非常感谢一些帮助和指导!

这是我得到的错误

Unhandled Exception: NoSuchMethodError: The getter 'id' was called on null.
Receiver: null
Tried calling: id

这是来自 user.dart

import 'package:cloud_firestore/cloud_firestore.dart';

class User {
  final String id;
  final String profileName;
  final String username;
  final String photoUrl;
  final String url;
  final String email;
  final String bio;
  final String createdAt;

  User({
    this.id,
    this.profileName,
    this.username,
    this.photoUrl,
    this.url,
    this.email,
    this.bio,
    this.createdAt,
  });

  factory User.fromDocument(DocumentSnapshot doc) {
    return User(
      id: doc.documentID,
      email: doc['email'],
      username: doc['username'],
      photoUrl: doc['photoUrl'],
      url: doc['url'],
      profileName: doc['profileName'],
      bio: doc['bio'],
      createdAt: doc['createdAt'],
    );
  }
}

这是来自 Signup.dart

错误指向 usersReference.document 行。

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:buddiesgram/models/user.dart';
import 'package:buddiesgram/pages/HomePage.dart';
import 'package:shared_preferences/shared_preferences.dart';


class SignupPage extends StatefulWidget {

  static final String id = 'signup_page';
  final DateTime timestamp = DateTime.now();
  User currentUser;

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

class _SignupPageState extends State<SignupPage> {
  final  FirebaseAuth auth = FirebaseAuth.instance;
  final _formKey = GlobalKey<FormState>();
  String username, email, password;
  SharedPreferences preferences;

  checkIfSignedIn() async {
    auth.onAuthStateChanged.listen((user) {

      if (user != null) {
        Navigator.push(context, MaterialPageRoute(builder: (context) => HomePage()));
      }
    });

    @override
    void initState() {
      super.initState();
      this.checkIfSignedIn();
    }
  }

  saveUserInfoToFireStore() async {

    preferences = await SharedPreferences.getInstance();
    DocumentSnapshot documentSnapshot = await usersReference.document(currentUser.id).get();

    if(!documentSnapshot.exists) {
      usersReference.document(currentUser.id).setData({
        "id": currentUser.id,
        "profileName": currentUser.profileName,
        "username": currentUser.username,
        "photoUrl": currentUser.photoUrl,
        "email": currentUser.email,
        "bio": "",
        "timestamp": timestamp,
        "talkingTo": null,
      });

      //Write data to local
      //currentUser = currentUser as User;
      //await preferences.setString("id", currentUser.id);
      //await preferences.setString("profileName", currentUser.profileName);
      //await preferences.setString("photoUrl", currentUser.photoUrl);

      await followersReference.document(currentUser.id).collection("userFollowers").document(currentUser.id).setData({});

      documentSnapshot = await usersReference.document(currentUser.id).get();
    }

    currentUser = User.fromDocument(documentSnapshot);
  }

  signUp() async {
    if(_formKey.currentState.validate()) {
      _formKey.currentState.save();

      try{
        AuthResult authResult = await auth.createUserWithEmailAndPassword(email: email, password: password);
        FirebaseUser signedInUser = authResult.user;
        if(signedInUser != null) {
        saveUserInfoToFireStore();
        }
        Navigator.push(context, MaterialPageRoute(builder: (context) => HomePage()));
      }
      catch(e) {
        print(e);
      }
    }
  }

这是来自 Timeline.dart

错误指向这两种方法的两条 QuerySnapshot 行。

retrieveTimeLine() async {
    QuerySnapshot querySnapshot = await timelineReference.document(currentUser.id)
        .collection("timelinePosts").orderBy("timestamp", descending: true).getDocuments();

    List<Post> allPosts = querySnapshot.documents.map((document) => Post.fromDocument(document)).toList();

    setState(() {
      this.posts = allPosts;
    });
  }

  retrieveFollowings() async {
    QuerySnapshot querySnapshot = await followingReference.document(currentUser.id)
        .collection("userFollowing").getDocuments();

    setState(() {
      followingsList = querySnapshot.documents.map((document) => document.documentID).toList();
    });
  }

如果我遗漏了任何内容,请告诉我,这可能会有所帮助。

【问题讨论】:

  • 似乎currentUsernull,你能显示一些它被初始化的代码吗?
  • 我在 Signup.dart 顶部的 Stateful Widget 下方有 User currentUser;。我将编辑我的问题以显示整个注册页面。 @JideGuru
  • @Indigo 从表面上看,你从来没有给currentUser赋值
  • 我现在正在尝试为它分配一个值。会是这样的吗? final String currentUser; SignupPage({this.currentUser}); 还是我走远了?
  • 这可行

标签: flutter dart google-cloud-firestore firebase-authentication


【解决方案1】:

currentUser 为 null,因为您没有初始化该类。例如:

  saveUserInfoToFireStore() async {
    currentUser = User(); //initialize
    preferences = await SharedPreferences.getInstance();
    DocumentSnapshot documentSnapshot = await usersReference.document(currentUser.id).get();

当然上面的代码还是不行,因为id等于null。如果数据库中的文档 id 等于用户 uid,则执行以下操作:

User loggedInUser;

  saveUserInfoToFireStore() async {
     var user = FirebaseAuth.instance.currentUser();
     loggedInUser = User(id : user.uid);
    preferences = await SharedPreferences.getInstance();
    DocumentSnapshot documentSnapshot = await usersReference.document(loggedInUser.id).get();

所以在这里您从 Firebase 身份验证中获取用户的 uid,然后由于您使用可选的命名参数,您可以使用 id 属性初始化 User 类并在 document() 方法中使用它.

【讨论】:

    【解决方案2】:

    转到 payment.dart 并启用结帐页面的选项

    并禁用原生选项

    【讨论】:

    • don't post your code as images。首先,我们要复制/粘贴它,其次搜索引擎无法索引该信息。所以请确保任何文本信息实际上是以文本形式提供的。
    猜你喜欢
    • 2021-06-03
    • 2020-09-28
    • 1970-01-01
    • 2020-11-01
    • 2022-01-16
    • 2021-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多