Home > Enterprise >  flutter and firebase error: type 'String?' can't be assigned to the parameter type &#
flutter and firebase error: type 'String?' can't be assigned to the parameter type &#

Time:09-05

I am creating a workout app using flutter & firebase. I have an ExerciseStream class which contains a StreamBuilder widget. in the StreamBuilder contains a ListView. in the ListView I pass the ExerciseCard class. In the ExerciseCard class I have if statements which determines which type of card I wanna return. A CardiovascularCard and a StrengthCard. but I get an error inside the if statements.

solution

instead of data!.docs[widget.index][exerciseType] == strength I did this data!.docs[widget.index]['exerciseType'] == strength and it worked. I was missing the quotes around exercisetype

error

when I hover over data!.docs[widget.index][exerciseType] as String == 'strength' in ExerciseCard Class I get this error:

The argument type 'String?' can't be assigned to the parameter type 'Object'

where is the 'object' in this situation?

code

ExerciseStream

class _ExerciseStreamState extends State<ExerciseStream> {
  @override
  Widget build(BuildContext context) {
    bool? firstLoad = false;
    CollectionReference users = FirebaseFirestore.instance.collection('users');
    return StreamBuilder<QuerySnapshot>(
        stream: users
            .doc(FirebaseAuth.instance.currentUser?.uid.toString())
            .collection('workout')
            .orderBy('exerciseName', descending: true)
            .snapshots(),
        builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
          List<Map<String, dynamic>?>? documentData = snapshot.data?.docs
              .map((e) => e.data() as Map<String, dynamic>?)
              .toList();

          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(child: CircularProgressIndicator());
          } else {
            if (snapshot.hasError) {
              return const Center(child: Text('Something went wrong'));
            } else {
              if (snapshot.data!.size == 0) {
                firstLoad = false;
                Future.delayed(Duration.zero, () => ExerciseTypeDialog(context))
                    .then((_) => firstLoad = true);
                return const SizedBox(height: 0.0);
              } else {
                firstLoad = true;
                print('documentData = $documentData');
                return Expanded(
                  child: ListView.builder(
                      itemCount: snapshot.data!.size,
                      itemBuilder: (context, index) {
                        return CardiovascularCard(snapshot, index);
                      }),
                );
              }
            }
          }
        });
  }
}

ExerciseTypeDialog

TextEditingController exerciseNameController = TextEditingController();
final uid = FirebaseAuth.instance.currentUser?.uid;
String? exerciseType;
String? strength = 'Strength';
String? cardiovascualar = 'Cardiovascular';
Future<void> ExerciseTypeDialog(BuildContext context) {
  return showDialog(
      barrierDismissible: firstLoad ?? true,
      context: context,
      builder: (context) {
        return AlertDialog(
          backgroundColor: Colors.blueGrey,
          title: const Text('Exercise type'),
          content: Column(mainAxisSize: MainAxisSize.min, children: [
            ListTile(
              onTap: () {
                exerciseType = strength;
                Navigator.pop(context);
                Future.delayed(
                    Duration.zero,
                    () => ExerciseNameDialog(
                        context, exerciseType!, strength, cardiovascualar));
              },
              title: Text(strength!),
            ),
            ListTile(
              onTap: () {
                exerciseType = cardiovascualar;
                Navigator.pop(context);
                Future.delayed(
                    Duration.zero,
                    () => ExerciseNameDialog(
                        context, exerciseType!, strength, cardiovascualar));
              },
              title: Text(cardiovascualar!),
            ),
          ]),
        );
      });
}

ExerciseNameDialog

TextEditingController exerciseNameController = TextEditingController();
final uid = FirebaseAuth.instance.currentUser?.uid;
Future<void> ExerciseNameDialog(
    BuildContext context, String exerciseType, strength, cardiovascualar) {
  return showDialog(
      barrierDismissible: firstLoad ?? true,
      context: context,
      builder: (context) {
        return AlertDialog(
          backgroundColor: Colors.blueGrey,
          title: Text(exerciseType),
          content: TextField(
            controller: exerciseNameController,
          ),
          actions: [
            GradientElevatedButton(
                onPressed: () async {
                  if (exerciseType == strength &&
                      exerciseNameController.text.isNotEmpty) {
                    print(exerciseType);
                    await FirebaseFirestore.instance
                        .collection('users')
                        .doc(uid)
                        .collection('workout')
                        .add({
                      'exerciseName': exerciseNameController.text,
                      'reps': 0.toString(),
                      'sets': 0.toString(),
                      'weight': 0.0.toString(),
                      'rest': 0.0.toString(),
                      'exerciseType': exerciseType
                    });
                    exerciseNameController.clear();
                    Navigator.pop(context);
                  } else {
                    if (exerciseType == cardiovascualar &&
                        exerciseNameController.text.isNotEmpty) {
                      await FirebaseFirestore.instance
                          .collection('users')
                          .doc(uid)
                          .collection('workout')
                          .add({
                        'exerciseName': exerciseNameController.text,
                        'caloriesBurnt': 0,
                        'time': 0.0,
                        'exerciseType': exerciseType
                      });
                      exerciseNameController.clear();
                      Navigator.pop(context);
                    } else {
                      SnackBar _snackBar = const SnackBar(
                        content: Text("Text field can't be empty"),
                      );
                      ScaffoldMessenger.of(context).showSnackBar(_snackBar);
                    }
                  }
                },
                child: const Text(
                  'ADD',
                  style: TextStyle(color: Colors.white),
                ))
          ],
        );
      });
}

ExerciseCard

class ExerciseCard extends StatefulWidget {
  AsyncSnapshot<QuerySnapshot> snapshot;
  int index;
  ExerciseCard(this.snapshot, this.index, {Key? key}) : super(key: key);

  @override
  State<ExerciseCard> createState() => _ExerciseCardState();
}

class _ExerciseCardState extends State<ExerciseCard> {
  @override
  Widget build(BuildContext context) {
    final data = widget.snapshot.data;

    if (data!.docs[widget.index][exerciseType] as String == 'strength') {
      return StrengthCard(widget.snapshot, widget.index);
    } else if (data.docs[widget.index][exerciseType].toString() ==
        'cardiovascualar') {
      return CardiovascularCard(widget.snapshot, widget.index);
    } else {
      Future.delayed(Duration.zero, () => ExerciseTypeDialog(context));
      return const SizedBox(height: 0.0);
    }
  }
}

CardiovascularCard

class CardiovascularCard extends StatefulWidget {
  AsyncSnapshot<QuerySnapshot> snapshot;
  int index;
  CardiovascularCard(this.snapshot, this.index, {Key? key})
      : super(key: key);

  @override
  State<CardiovascularCard> createState() => _CardiovascularCardState();
}

String deleteExerciseText = 'Delete exercise';
final uid = FirebaseAuth.instance.currentUser?.uid;
TextEditingController _calorieController = TextEditingController();
TextEditingController _timeController = TextEditingController();

class _CardiovascularCardState extends State<CardiovascularCard> {
  
  @override
  Widget build(BuildContext context) {
    String deleteExerciseText = 'Delete exercise';
    final uid = FirebaseAuth.instance.currentUser?.uid;
    final data = widget.snapshot.data;
    final exerciseId = data!.docs[widget.index].reference.id;
    void deleteExerciseFunction() {
      FirebaseFirestore.instance
          .runTransaction((Transaction myTransaction) async {
        myTransaction.delete(data.docs[widget.index].reference);
      });
    }

    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(children: [
        Card(
          elevation: 8,
          color: const Color.fromARGB(255, 81, 108, 122),
          child: Column(
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.start,
                children: [
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Text(
                      data.docs[widget.index]['exerciseName'],
                      style: const TextStyle(
                          fontSize: 20.0, fontWeight: FontWeight.bold),
                    ),
                  ),
                  const Divider(thickness: 1.0),
                ],
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: const [
                  Text(
                    'Calories',
                    style: TextStyle(color: Colors.white),
                  ),
                  Text(
                    'Time',
                    style: TextStyle(color: Colors.white),
                  ),
                ],
              ),
              Slidable(
                endActionPane: ActionPane(
                  motion: const ScrollMotion(),
                  children: [
                    SlidableAction(
                      onPressed: (context) {
                        DialogInstance(context, deleteExerciseFunction,
                            deleteExerciseText);
                      },
                      label: 'Delete',
                      backgroundColor: Colors.red,
                      icon: Icons.delete,
                    )
                  ],
                ),
                child: ListTile(
                  title: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: [
                      SizedBox(
                        width: MediaQuery.of(context).size.width * 0.145,
                        child: TextField(
                          style: const TextStyle(fontWeight: FontWeight.bold),
                          cursorColor: Colors.white,
                          onSubmitted: (value) async {
                            FirebaseFirestore.instance.runTransaction(
                                (Transaction myTransaction) async {
                              FirebaseFirestore.instance
                                  .collection('users')
                                  .doc(uid)
                                  .collection('workout')
                                  .doc(exerciseId)
                                  .update({'caloriesBurnt': value});
                            });
                          },
                          textAlign: TextAlign.center,
                          keyboardType: TextInputType.number,
                          controller: _calorieController,
                          decoration: InputDecoration(
                              focusedBorder: const UnderlineInputBorder(
                                borderSide: BorderSide(color: Colors.white),
                              ),
                              hintText: data.docs[widget.index]['caloriesBurnt']
                                  .toString()),
                        ),
                      ),
                      SizedBox(
                        width: MediaQuery.of(context).size.width * 0.145,
                        child: TextField(
                          style: const TextStyle(fontWeight: FontWeight.bold),
                          cursorColor: Colors.white,
                          onSubmitted: (value) async {
                            FirebaseFirestore.instance.runTransaction(
                                (Transaction myTransaction) async {
                              FirebaseFirestore.instance
                                  .collection('users')
                                  .doc(uid)
                                  .collection('workout')
                                  .doc(exerciseId)
                                  .update({'time': value});
                            });
                          },
                          textAlign: TextAlign.center,
                          keyboardType: TextInputType.number,
                          controller: _timeController,
                          decoration: InputDecoration(
                              focusedBorder: const UnderlineInputBorder(
                                borderSide: BorderSide(color: Colors.white),
                              ),
                              hintText:
                                  data.docs[widget.index]['time'].toString()),
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
      ]),
    );
  }
}

StrengthCard

class StrengthCard extends StatefulWidget {
  final AsyncSnapshot<QuerySnapshot> snapshot;
  int index;

  StrengthCard(this.snapshot, this.index, {Key? key}) : super(key: key);

  @override
  State<StrengthCard> createState() => _StrengthCardState();
}

String deleteExerciseText = 'Delete exercise';
final uid = FirebaseAuth.instance.currentUser?.uid;
late TextEditingController _setsController;
late TextEditingController _repsController;
late TextEditingController _weightController;
late TextEditingController _restController;

class _StrengthCardState extends State<StrengthCard> {
  @override
  void initState() {
    _repsController = TextEditingController();
    _setsController = TextEditingController();
    _weightController = TextEditingController();
    _restController = TextEditingController();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    final data = widget.snapshot.data;
    final exerciseId = data!.docs[widget.index].reference.id;
    void deleteExerciseFunction() {
      FirebaseFirestore.instance
          .runTransaction((Transaction myTransaction) async {
        myTransaction.delete(data.docs[widget.index].reference);
      });
    }

    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(children: [
        Card(
          elevation: 8,
          color: const Color.fromARGB(255, 81, 108, 122),
          child: Column(
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.start,
                children: [
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Text(
                      data.docs[widget.index]['exerciseName'],
                      style: const TextStyle(
                          fontSize: 20.0, fontWeight: FontWeight.bold),
                    ),
                  ),
                  const Divider(thickness: 1.0),
                ],
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: const [
                  Text(
                    'Reps',
                    style: TextStyle(color: Colors.white),
                  ),
                  Text(
                    'Sets',
                    style: TextStyle(color: Colors.white),
                  ),
                  Text(
                    'Weight',
                    style: TextStyle(color: Colors.white),
                  ),
                  Text(
                    'rest',
                    style: TextStyle(color: Colors.white),
                  )
                ],
              ),
              Slidable(
                endActionPane: ActionPane(
                  motion: const ScrollMotion(),
                  children: [
                    SlidableAction(
                      onPressed: (context) {
                        DialogInstance(context, deleteExerciseFunction,
                            deleteExerciseText);
                      },
                      label: 'Delete',
                      backgroundColor: Colors.red,
                      icon: Icons.delete,
                    )
                  ],
                ),
                child: ListTile(
                  title: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: [
                      SizedBox(
                        width: MediaQuery.of(context).size.width * 0.145,
                        child: TextField(
                          style: const TextStyle(fontWeight: FontWeight.bold),
                          cursorColor: Colors.white,
                          onSubmitted: (value) async {
                            FirebaseFirestore.instance.runTransaction(
                                (Transaction myTransaction) async {
                              FirebaseFirestore.instance
                                  .collection('users')
                                  .doc(uid)
                                  .collection('workouts')
                                  .doc(exerciseId)
                                  .update({'reps': value});
                            });
                          },
                          textAlign: TextAlign.center,
                          keyboardType: TextInputType.number,
                          controller: _repsController,
                          decoration: InputDecoration(
                              focusedBorder: const UnderlineInputBorder(
                                borderSide: BorderSide(color: Colors.white),
                              ),
                              hintText:
                                  data.docs[widget.index]['reps'].toString()),
                        ),
                      ),
                      SizedBox(
                        width: MediaQuery.of(context).size.width * 0.145,
                        child: TextField(
                          style: const TextStyle(fontWeight: FontWeight.bold),
                          cursorColor: Colors.white,
                          onSubmitted: (value) async {
                            FirebaseFirestore.instance.runTransaction(
                                (Transaction myTransaction) async {
                              FirebaseFirestore.instance
                                  .collection('users')
                                  .doc(uid)
                                  .collection('workout')
                                  .doc(exerciseId)
                                  .update({'sets': value});
                            });
                          },
                          textAlign: TextAlign.center,
                          keyboardType: TextInputType.number,
                          controller: _setsController,
                          decoration: InputDecoration(
                              focusedBorder: const UnderlineInputBorder(
                                borderSide: BorderSide(color: Colors.white),
                              ),
                              hintText:
                                  data.docs[widget.index]['sets'].toString()),
                        ),
                      ),
                      SizedBox(
                        width: MediaQuery.of(context).size.width * 0.145,
                        child: TextField(
                          style: const TextStyle(fontWeight: FontWeight.bold),
                          cursorColor: Colors.white,
                          onSubmitted: (value) async {
                            FirebaseFirestore.instance.runTransaction(
                                (Transaction myTransaction) async {
                              FirebaseFirestore.instance
                                  .collection('users')
                                  .doc(uid)
                                  .collection('workout')
                                  .doc(exerciseId)
                                  .update({'weight': value});
                            });
                          },
                          textAlign: TextAlign.center,
                          keyboardType: TextInputType.number,
                          controller: _weightController,
                          decoration: InputDecoration(
                              focusedBorder: const UnderlineInputBorder(
                                borderSide: BorderSide(color: Colors.white),
                              ),
                              hintText:
                                  data.docs[widget.index]['weight'].toString()),
                        ),
                      ),
                      SizedBox(
                        width: MediaQuery.of(context).size.width * 0.145,
                        child: TextField(
                          style: const TextStyle(fontWeight: FontWeight.bold),
                          cursorColor: Colors.white,
                          onSubmitted: (value) async {
                            FirebaseFirestore.instance.runTransaction(
                                (Transaction myTransaction) async {
                              FirebaseFirestore.instance
                                  .collection('users')
                                  .doc(uid)
                                  .collection('workout')
                                  .doc(exerciseId)
                                  .update({'rest': value});
                            });
                          },
                          textAlign: TextAlign.center,
                          keyboardType: TextInputType.number,
                          controller: _restController,
                          decoration: InputDecoration(
                              focusedBorder: const UnderlineInputBorder(
                                borderSide: BorderSide(color: Colors.white),
                              ),
                              hintText:
                                  data.docs[widget.index]['rest'].toString()),
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
      ]),
    );
  }
}

Thanks!

CodePudding user response:

If you are sure that it's type is string, try cast it with as keyword

CodePudding user response:

Try this

data!.docs[widget.index][exerciseType]?.toString() == 'strength'

Remove '?' if the variable is non-nullable

CodePudding user response:

instead of data!.docs[widget.index][exerciseType] == strength I did this data!.docs[widget.index]['exerciseType'] == strength and it worked

  • Related