0

I am about to log in a user anonymously. I use the following code:

class ToDo1 extends StatefulWidget {
  @override
  _ToDo1State createState() => _ToDo1State();
}

class _ToDo1State extends State<ToDo1> {

  User? user;
  late DatabaseService database;

  void toggleDone(String key, bool value) {
    database.setTodo(key, !value);
  }

  Future<void> connectToFirebase() async{
    final FirebaseAuth auth = FirebaseAuth.instance;
    UserCredential result = await FirebaseAuth.instance.signInAnonymously();
    user = result.user;
    database = DatabaseService(user!.uid);

    if (!(await database.checkIfUserExists())) {
      database.setTodo('To-Do anlegen', false);
    }
  }

    @override
  void initState() {
    // TODO: implement initState
    super.initState();
    connectToFirebase();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Center(
            child: Text(
          'Stufe 1',
          style: TextStyle(
              fontStyle: FontStyle.italic,
              decoration: TextDecoration.underline),
        )),
        backgroundColor: Color.fromRGBO(35, 112, 192, 1),
      ),
      body: Center(child: ElevatedButton(
        onPressed: () {print(DatabaseService(user!.uid));},
        child: Icon(Icons.question_answer_outlined)
      ))
    );
  }
}

That's the class which interacts with firebase:

import 'package:cloud_firestore/cloud_firestore.dart';

class DatabaseService {

  final String userID;
  DatabaseService(this.userID);

  final CollectionReference userTodos =
      FirebaseFirestore.instance.collection('userTodos');

  Future setTodo(String item, bool value) async {
    return await userTodos.doc(userID).set(
      {item:value}, SetOptions(merge: true));
  }

    Future deleteTodo(String key) async {
      return await userTodos.doc(userID).update(
        {key: FieldValue.delete(),}
      );
    }

    Future checkIfUserExists() async {
    if((await userTodos.doc(userID).get()).exists) {
      return true;
    }
      else {
        return false;
      }
    }

  Stream<DocumentSnapshot> getTodos() {
    return userTodos.doc(userID).snapshots();
  }
}

As soon as I click on the button, which should give me the UserID, the following error occurs:

Null check operator used on a null value.


Although a user is listed in the firebase.


enter image description here


I hope I have provided all the necessary data so that the problem can be solved. If not, just write it to me and I will try to send you the material you need.

Lars
  • 65
  • 1
  • 7
  • As the error message says, you used a null check operator on a null value. That is, you did `variable!` where `variable` is `null`. Figure out where that occurs (likely one of the lines where you do `user!.uid`) and explicitly check if `user` is `null` first. – jamesdlin Sep 10 '21 at 09:24

1 Answers1

1

where did you called this function ??

 Future<void> connectToFirebase() async{
    final FirebaseAuth auth = FirebaseAuth.instance;
    UserCredential result = await FirebaseAuth.instance.signInAnonymously();
    user = result.user;
    database = DatabaseService(user!.uid);

  if (!(await database.checkIfUserExists())) {
      database.setTodo('To-Do anlegen', false);
    }
  }

if you are not, user is already null you need to assign new value

  • I'am calling this function with an initeState function. I forgot to add it to the code. But also with the initeState function, I'm getting the same error. Do you have any idea how to fix this error? – Lars Sep 10 '21 at 14:17
  • 1
    I think the problem might be that the `connectToFirebase` method is async, so by the time it executes, the build method already threw an error. If that's the case, I would make the user variable a future and use a `FutureBuilder` on the build method – h8moss Sep 10 '21 at 18:03
  • I think about answer is correct. async methods will take more time and run in separate Thread.so make user variable Future and pass it to FutureBuilder as a future – Shakthi Hettiarachchi Sep 10 '21 at 20:04