# #firebase #flutter #dart #google-cloud-firestore
Вопрос:
Я начинающий разработчик flutter и пытаюсь извлечь данные из Firestore с помощью Streambuilder. На прошлой неделе код работал нормально, на этой неделе я не смог отобразить пользовательские данные из Firestore.
Ошибки, которые я получаю, заключаются в следующем:
тип «Null» не является подтипом типа «Строка». Соответствующий виджет, вызывающий ошибки, был StreamBuilder<DocumentSnapshot<Объект?><Объект?>>
Рендерфлекс справа заполнен 99833 пикселями. Соответствующим виджетом, вызывающим ошибки, была строка
Вот мой код
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_application_1/main_views/account_method.dart';
class SettingsPage extends StatefulWidget {
@override
_SettingsPageState createState() => _SettingsPageState();
}
FirebaseAuth _auth = FirebaseAuth.instance;
final uid = _auth.currentUser!.uid;
class _SettingsPageState extends State<SettingsPage> {
String errorMessage = '';
@override
Widget build(BuildContext context) {
var boldFont = TextStyle(fontFamily: 'Inter', fontWeight: FontWeight.w600);
final Stream<DocumentSnapshot<Map<String, dynamic>>> db =
FirebaseFirestore.instance
.collection('users')
.doc(uid)
.collection('Personal details')
.doc()
.snapshots();
return Scaffold(
appBar: AppBar(
titleSpacing: 30,
automaticallyImplyLeading: false,
backgroundColor: Color.fromRGBO(1, 67, 55, 1),
toolbarHeight: 100,
title: new Text(
'Settings',
style: TextStyle(
color: Color.fromRGBO(255, 255, 255, 1),
fontFamily: 'Poppins',
fontSize: 25,
letterSpacing: 1.2,
fontWeight: FontWeight.bold,
height: 1),
),
),
body: SingleChildScrollView(
child: Container(
padding: EdgeInsets.all(30),
color: Color.fromRGBO(246, 246, 246, 1),
child: Column(children: [
SizedBox(
height: 30,
),
Container(
padding: EdgeInsets.only(left: 30, right: 30),
decoration: BoxDecoration(),
child: Text('Account',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
fontFamily: 'Inter'))),
Padding(
padding: EdgeInsets.all(30.0),
child: Column(
children: [
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('First name'),
SizedBox(width: 40),
StreamBuilder<DocumentSnapshot>(
stream: db,
builder: (BuildContext context,
AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.hasError)
return Text('Something went wrong');
if (snapshot.connectionState ==
ConnectionState.waiting)
return CircularProgressIndicator();
dynamic data = snapshot.data!.data();
return Text(data['First name']);
},
),
]),
Divider(color: Colors.black),
SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Last name'),
SizedBox(width: 40),
StreamBuilder<DocumentSnapshot>(
stream: db,
builder: (BuildContext context,
AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.hasError)
return Text('Something went wrong');
if (snapshot.connectionState ==
ConnectionState.waiting)
return CircularProgressIndicator();
dynamic data = snapshot.data!.data();
return Text(data['Last name'], style: boldFont);
},
),
],
),
Divider(color: Colors.black),
SizedBox(
height: 10,
),
InkWell(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Change password'),
SizedBox(width: 40),
Icon(Icons.arrow_forward, size: 18, color: Colors.black)
],
),
),
Divider(color: Colors.black),
SizedBox(
height: 10,
),
InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AccountMethod()),
);
},
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Accounts'),
SizedBox(width: 40),
Icon(
Icons.arrow_forward,
color: Colors.black,
size: 19.0,
),
],
),
),
Divider(color: Colors.black),
SizedBox(
height: 30,
),
ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
Color.fromRGBO(1, 67, 55, 1)),
shape:
MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20))),
),
child: Text('Log out'),
onPressed: () async {
try {
await FirebaseAuth.instance.signOut();
errorMessage = '';
} on FirebaseAuthException catch (error) {
errorMessage = error.message!;
}
setState(() {});
Navigator.of(context).pushReplacementNamed('/signIn');
}),
SizedBox(height: 15),
],
),
)
]),
),
),
);
}
}
А вот скриншот базы данных firestore.
скриншот базы данных firestore
Заранее благодарим вас за любую помощь
Комментарии:
1. Опубликуйте полный код страницы настроек. Что-то возвращается
null
туда, куда должно вернутьсяString
(вероятноLast name
). Убедитесь, что в документе пользователя есть полеLast name
(с точной прописной буквой и пробелом между ними). Также опубликуйте документ пользователя (скриншот firestore).2. Привет, Питер, я опубликовал полный код страницы настроек и документ пользователя в firestore. Я могу подтвердить, что поле введено как есть
Ответ №1:
Ладно, я думаю, что проблема отсюда.
final Stream<DocumentSnapshot<Map<String, dynamic>>> db =
FirebaseFirestore.instance
.collection('users')
.doc(uid)
.collection('Personal details')
.doc() // <-- error should be from here.
.snapshots();
Вы пытаетесь передать ссылку на документ, которая не существует. .doc()
возвращает несуществующую ссылку на документ. Скорее, используйте .doc('Path_to_the_document')
.
Поэтому добавьте путь к документу, который содержит Last name
поле.
Комментарии:
1. Так рад, что смог помочь.