skip to Main Content

I’m trying to make simple login logic using Firebase but can’t get rid of this error:

Exception has occurred.
DartError: Bad state: Cannot fire new event. Controller is already firing an event

Here is my code:

import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'package:identity_retro/models/user_model.dart';
import 'package:uuid/uuid.dart';

class DatabaseOperations {
  static final FirebaseDatabase database = FirebaseDatabase.instance;
  DatabaseReference ref = FirebaseDatabase.instance.ref();

  Future<UserModel?> getUserByEmail(String username) async {
    var response = await ref
        .child('users')
        .orderByChild('username')
        .equalTo(username)
        .once();

    if (!response.snapshot.exists) {
      return null;
    }

    var userMap = Map<String, dynamic>.from(response.snapshot.value as Map);
    var user =
        UserModel.fromJson(userMap);

    return user;
  }

  Future<UserModel?> getUserById(String id) async {
    var response =
        await ref.child('users').orderByChild('id').equalTo(id).once();

    if (!response.snapshot.exists) {
      return null;
    }

    var user =
        UserModel.fromJson(response.snapshot.value as Map<String, dynamic>);

    return user;
  }

  Future<bool> addUser(UserModel user, BuildContext context) async {
    if (await getUserByEmail(user.username!) != null)
    {
      if (context.mounted) {
        await showDialog(
            context: context,
            builder: (BuildContext context) {
              return AlertDialog(
                title: const Text('Error'),
                content: const Text('User already exists'),
                actions: <Widget>[
                  TextButton(
                    onPressed: () {
                      Navigator.of(context).pop();
                    },
                    child: const Text('OK'),
                  ),
                ],
              );
            });
      }

      return false;
    }

    var id = Uuid().v4();

    await ref.child('users/$id').set({'username': user.username, 'password': user.password});

    return await getUserById(id) != null;
  }
}

Exception happens in positive scenario when user doesn’t exists and it trying to make new one in this line:

await ref.child('users/$id').set({'username': user.username, 'password': user.password});

Stacktrace leads to database_reference_web.dart file line 51. It’s a set method

But it worth to mention than despite on the error user is created after all

2

Answers


  1. Chosen as BEST ANSWER

    Honestly have no idea, but following changes helped:

    from

    var response = await ref
        .child('users')
        .orderByChild('username')
        .equalTo(username)
        .once();
    

    to

    var response = await ref
        .child('users')
        .orderByChild('username')
        .equalTo(username)
        .get();
    

  2. Seems you attempt to update or read from a stream/controller while it’s still processing a previous event

    try this code

    Future<bool> addUser(UserModel user, BuildContext context) async {
      // Check if the user already exists by username
      if (await getUserByEmail(user.username!) != null) {
        if (context.mounted) {
          // Display an error dialog if the user exists
          await showDialog(
            context: context,
            builder: (BuildContext context) {
              return AlertDialog(
                title: const Text('Error'),
                content: const Text('User already exists'),
                actions: <Widget>[
                  TextButton(
                    onPressed: () {
                      Navigator.of(context).pop();
                    },
                    child: const Text('OK'),
                  ),
                ],
              );
            },
          );
        }
        return false;
      }
    
      // Generate a unique ID for the user
      var id = Uuid().v4();
    
      // Add the user to the Firebase database
      await ref.child('users/$id').set({
        'id': id, // Ensure that you store the ID in the user object
        'username': user.username,
        'password': user.password,
      });
    
      // Retrieve the user by ID to confirm the insertion
      var addedUser = await getUserById(id);
      return addedUser != null;
    }
    

    If still face any issue try to implement try catch and debug with breakpoints

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search