#firebase #flutter
# #firebase #flutter
Вопрос:
Я пытаюсь реализовать проверку, что если user DisplayName имеет значение null в firebase. Он должен перейти к форме, в которой он должен ввести свое имя. В настоящее время DisplayName в firebase по умолчанию имеет значение null . Но я получаю сообщение об ошибке.
Для текстового виджета должна быть предоставлена ненулевая строка.
‘package:flutter/src/widgets/text.dart’:
Неудачное утверждение: строка 360 поз 10: «данные! = null»
Row(
children: [
Container(
margin: EdgeInsets.only(bottom: 50, left: 30),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
//crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Welcome !"),
// ignore: unrelated_type_equality_checks
Text(snapshot.data.documents
.elementAt(index)['displayName']) !=
null
? Text(snapshot.data.documents
.elementAt(index)['displayName'])
: Navigator.pushNamed(context, '/UserDetail'),
],
),
),
],
),
Ответ №1:
Попробуйте это вместо этого.
Row(
children: [
Container(
margin: EdgeInsets.only(bottom: 50, left: 30),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
//crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Welcome !"),
// ignore: unrelated_type_equality_checks
snapshot.data.documents.elementAt(index)['displayName'] !=
null
? Text(snapshot.data.documents
.elementAt(index)['displayName'])
: Navigator.pushNamed(context, '/UserDetail'),
],
),
),
],
),
Text
Виджет вам этого не даст null
. Только те данные, которые вы предоставляете, могут быть null
Комментарии:
1. Это сработало, но получить это сейчас. Было выдано следующее утверждение building: setState() или markNeedsBuild(), вызванные во время сборки. Этот виджет наложения не может быть помечен как требующий сборки, поскольку фреймворк уже находится в
2. Куда вы вызываете setState? Покажите весь ваш код
Ответ №2:
Вы многое упускаете. Давайте попробуем это исправить!
- Игнорировать возможные ошибки — плохая идея.
- Никогда не пишите
// ignore: unrelated_type_equality_checks
- Что пытается сделать ваш код? Нам нужно знать, что вам нужно.
Что не так с тем, что вы написали?
// ignore:
заставляет линтер игнорировать проблему определенного типа. Вы проигнорировалиunrelated_type_equality_checks
, что означает, что вы не считаете ошибкой сравнивать два разных типа данных. Это нехорошо.2
и"someString"
это разные типы данных. Когда вы сравниваете их:2 == "someString"
он никогда не будет оцениватьtrue
. Так будет всегдаfalse
.- Фактическое сравнение, которое вы написали, всегда верно.
Text(snapshot.data.documents
.elementAt(index)['displayName']) !=
null
? Text(snapshot.data.documents
.elementAt(index)['displayName'])
: Navigator.pushNamed(context, '/UserDetail')
Вот это сравнение только в одной строке:
Text(snapshot.data.documents.elementAt(index)['displayName']) != null
Давайте упростим это, чтобы показать, что не так. Посмотрите, почему сравнение всегда верно?
Text('displayName') != null // always true
Вы, вероятно, хотели написать: (Я только удалил Text() из сравнения, которое вы написали.)
snapshot.data.documents
.elementAt(index)['displayName'] !=
null
? Text(snapshot.data.documents
.elementAt(index)['displayName'])
: Navigator.pushNamed(context, '/UserDetail')
Но этот код по-прежнему не имеет смысла! Если отображаемое имя документа не было null, Text
виджет является результатом сравнения. Если отображаемое имя было null, мы вызываем Navigator.pushNamed
which не является функцией, которая возвращает a Widget
. Нам нужны обе части тернарного оператора, чтобы возвращать a Widget
, и только Text()
часть возвращает a Widget
. Вызов Navigator.pushNamed
не возвращает a Widget
, что является ошибкой.
Вот как вы можете исправить это несоответствие типов:
snapshot.data.documents
.elementAt(index)['displayName'] !=
null
? Text(snapshot.data.documents
.elementAt(index)['displayName'])
: Text("Something went wrong!")
Но есть еще одна проблема после того, как мы исправим это несоответствие типов в троичном операторе. Мы повторяемся! snapshot.data.documents.elementAt(index)['displayName']
записывается дважды! Не повторяйтесь
var name = snapshot.data.documents.elementAt(index)['displayName'];
name != null
? Text(name)
: Text("Something went wrong!")
Видите, как мы получаем Text
Widget
независимо от того, что? Мы можем сократить его!
var name = snapshot.data.documents.elementAt(index)['displayName'];
Text(name != null ? name : "Something went wrong!")
Эта проверка на нуль настолько распространена, что Dart предоставляет оператору ??
для ее выполнения.
var name = snapshot.data.documents.elementAt(index)['displayName'];
Text(name ?? "Something went wrong!")
Но в этом коде все еще есть ошибки.
Я должен предположить, что snapshot
это имеет тип данных AsyncSnapshot
, потому что ваш пример не был завершен. AsyncSnapshot
может быть ошибка, и это могут быть данные. Вы должны проверить, прежде чем использовать данные!
if (snapshot.hasError) return Text("Oops!");
var name = snapshot.data.documents.elementAt(index)['displayName'];
Text(name ?? "Something went wrong!")
Ожидание получения документа не является ошибкой. Это означает, что нам нужно проверить, есть ли AsyncSnapshot
у него данные!
if (snapshot.hasError) return Text("Oops!");
if (!snapshot.hasData) return Text("No data yet!");
var name = snapshot.data.documents.elementAt(index)['displayName'];
Text(name ?? "Something went wrong!")
Отлично! Теперь мы уверены, что в снимке есть данные! Но что, если эти данные представляют собой пустой список?
if (snapshot.hasError) return Text("Oops!");
if (!snapshot.hasData) return Text("No data yet!");
if (snapshot.data.documents.isEmpty) return Text("No documents!");
var name = snapshot.data.documents.elementAt(index)['displayName'];
Text(name ?? "Something went wrong!")
Но что, если мы получим только один документ в списке документов, и index
есть 5
? Это было бы RangeError
. Что делать, если displayName
ее нет в документе? Это было бы KeyError
.
Если вы уверены, что ваш index
файл не будет слишком большим и что все ваши документы имеют a displayName
, не стесняйтесь игнорировать возможные ошибки.
Вот что мы получаем, когда исправляем все недоразумения.
if (snapshot.hasError) return Text("Oops!");
if (!snapshot.hasData) return Text("No data yet!");
if (snapshot.data.documents.isEmpty) return Text("No documents!");
var name = snapshot.data.documents.elementAt(index)['displayName'];
return Row(
children: [
Container(
margin: EdgeInsets.only(bottom: 50, left: 30),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Welcome !"),
Text(name ?? "Something went wrong!")
],
),
),
],
);