«пакет:flutter/src/widget/text.dart»: Проверенное утверждение: строка 378 pos 10; «данные != null»: Для текстового виджета должна быть предоставлена ненулевая строка

# #firebase #flutter #dart

Вопрос:

У меня появился красный экран на мобильном телефоне при доступе к record_patien.

вот код

 import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'package:sensor_detak_jantung/models/sensor.dart';
import 'package:sensor_detak_jantung/models/user.dart';
import 'package:sensor_detak_jantung/screens/authenticate/sign_in.dart';
import 'package:firebase_auth/firebase_auth.dart' as firebase_auth;
import 'package:sensor_detak_jantung/services/db_path.dart';

class RecordPatient extends StatefulWidget {
  const RecordPatient({Key key}) : super(key: key);

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

class _RecordPatient extends State<RecordPatient> {

  final databaseReference = FirebaseDatabase.instance.reference();
  final _auth = firebase_auth.FirebaseAuth.instance;
  final TextEditingController tokenController = TextEditingController();
  User userInfo;
  firebase_auth.User _user;
  Sensor sensorInfo;
  final _formKey = GlobalKey<FormState>();
  String bpm;
  void initState(){
    super.initState();
    this._user = _auth.currentUser;
    if(_user != null) {

  
 

Именно здесь я пытаюсь получить значение BPM

       databaseReference.child('Sensor').once().then((DataSnapshot snapshot) {
        bpm = snapshot.value['BPM']['Data'];
      });
 

Это для пользователя, этот код плавно запускается в другом классе.

       databaseReference.child(USER_KEY).child(_user.uid).once().then((snapshot) {
        userInfo = User.fromSnapshot(snapshot);
        setState(() { });
      });

    }
  }

  AppBar title(){
    return AppBar(
      backgroundColor: Colors.red[400],
      elevation: 0.0,
      title: Text('Hi ${userInfo?.userName}'),
      actions: <Widget>[
        FlatButton.icon(
          icon: Icon(Icons.person),
          label: Text('logout'),
          onPressed: () async {
            _auth.signOut().then((value) {
              Navigator.pushReplacement(context, new MaterialPageRoute(builder: (context) => SignIn()));
              setState(() {});
            });
          },
        ),
      ],
    );
  }

  @override


  Widget build(BuildContext context) {
    print (bpm);
    return Scaffold(
      body: Form(
        key: _formKey,
        child: ListView(
          padding: const EdgeInsets.fromLTRB(22.0, 0.0, 22.0, 22.0),
          children: [
            SizedBox(height: 40),
            title(),
            SizedBox(height: 40),
            Text (bpm),
          ],
        ),
      ),
    );
  }
}
 

это происходит, когда я пытаюсь получить Sensor ценность и users ценность.

я все еще учусь и экспериментирую, если кто-нибудь сможет объяснить мне, почему эта ошибка произошла простым способом, я буду очень признателен.

Ответ №1:

Как написано в ошибке, текстовый виджет получает нулевое значение, что является ошибкой, когда мы передаем что-то подобное в текст Text(null) . В вашем коде это возможно только в этом текстовом виджете, где bpm может быть равен нулю.

 Text (bpm),
 

Так что вы можете просто сделать это,

 databaseReference.child('Sensor').once().then((DataSnapshot snapshot) {
        bpm = snapshot.value['BPM']['Data']??"";
      });
 

чтобы исправить ошибку.

Комментарии:

1. Я считаю, что это тот же код, который я использую для получения bpm в первую очередь. но почему ты ставишь ?? в конце концов? так как большая часть моего кода является частью другого учебника. Поэтому я стараюсь этому научиться.

2. Я добавил нулевую проверку во вторую строку, где назначается bpm, чтобы она не могла быть нулевой. ?? является оператором проверки null, который проверяет, является ли что-то нулевым, и если это так, он просто возвращает то, что написано после этого, как в данном случае «».

3. Ах, я понимаю, и можно ли обновлять значение bpm каждый раз, когда меняется база данных, не обновляя экран

4. Для этого вы можете использовать StreamBuilder вместо FutureBuilder. Firebase также предоставляет поток, и вы можете найти о них больше информации.

Ответ №2:

Похоже snapshot.value['BPM']['Data']; , он возвращается null , поэтому ваш виджет Text() имеет null значение, которое недопустимо. Вам следует добавить нулевую проверку перед присвоением значения bpm текстовому виджету, возможно, что-то вроде этого:

 SizedBox(height: 40),
title(),
SizedBox(height: 40),
(bpm == null)?Text ("No BPM received"):Text(bpm),