#firebase #flutter #dart #firebase-realtime-database
#firebase #флаттер #dart #firebase-база данных в реальном времени
Вопрос:
Я могу получить этот результат из этих двух вещей (структура данных из Firebase Realtime Database
и приведенный ниже код).
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_swiper/flutter_swiper.dart';
class GetMealScreen extends StatefulWidget {
@override
_GetMealScreenState createState() => _GetMealScreenState();
}
class _GetMealScreenState extends State<GetMealScreen> {
DatabaseReference itemRef = FirebaseDatabase.instance.reference().child("testtest").child("test");
@override
Widget build(BuildContext context) {
return Scaffold(
body:
Container(
child:
FutureBuilder<DataSnapshot>(
future: itemRef.once(),
builder: (context, snapshot) {
List<String> menuList = [
snapshot.data.value["tt"].toString(),
];
final double card_width = 370;
final double card_upper_height = 210;
return
Container(
height: card_upper_height,
width: card_width,
child:
Padding(
padding: EdgeInsets.symmetric(vertical: 0, horizontal: 0),
child: Swiper(//
control: SwiperControl(
color: Colors.white,
),
pagination: SwiperPagination(
alignment: Alignment.bottomRight
),
itemCount: menuList.length,
itemBuilder: (BuildContext context, int index){
return
Text(
menuList[index],
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 40,
color: Colors.black,
),
);
},
),
),
);
},
),
),
);
}
}
но проблема в том, что всякий раз, когда я пытаюсь получить доступ к этому экрану, я получаю следующую ошибку.
Performing hot reload...
Syncing files to device AOSP on IA Emulator...
Reloaded 5 of 685 libraries in 702ms.
I/flutter (15990): hi
════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following NoSuchMethodError was thrown building FutureBuilder<DataSnapshot>(dirty, state: _FutureBuilderState<DataSnapshot>#84ed7):
The getter 'value' was called on null.
Receiver: null
Tried calling: value
The relevant error-causing widget was:
FutureBuilder<DataSnapshot> file:///Users/mingukkim/tubuc1.1.3/lib/GetMealMenu.dart:21:11
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1 _GetMealScreenState.build.<anonymous closure> (package:Tubuc/GetMealMenu.dart:26:31)
#2 _FutureBuilderState.build (package:flutter/src/widgets/async.dart:751:55)
#3 StatefulElement.build (package:flutter/src/widgets/framework.dart:4683:28)
#4 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4566:15)
...
════════════════════════════════════════════════════════════════════════════════════════════════════
Я думал, что это появилось, потому что snapshot.data.value["tt"].toString()
возвращает нулевое значение, но это не так, поэтому я не могу понять, что не так.. Кроме того, я нашел похожую проблему в Google, но я не смог найти проблему с FutureBuilder, подобную моей. Можете ли вы сказать мне, что не так?
Заранее благодарю вас.
Комментарии:
1. Вы пытаетесь получить доступ
snapshot.data.value
до завершения Future. Вам нужно обернуть это вif (snapshot.hasData)
, чтобы ваш код выполнялся после возвращения Future. Взгляните на класс на flutter.dev для хорошего примера: api.flutter.dev/flutter/widgets/FutureBuilder-class.html
Ответ №1:
Попробуйте следующее:
if(snapshot.hasData){
List<String> menuList = [
snapshot.data.value["tt"].toString(),
];
final double card_width = 370;
final double card_upper_height = 210;
return
Container(
height: card_upper_height,
width: card_width,
child:
Padding(
padding: EdgeInsets.symmetric(vertical: 0, horizontal: 0),
child: Swiper(//
control: SwiperControl(
color: Colors.white,
),
pagination: SwiperPagination(
alignment: Alignment.bottomRight
),
itemCount: menuList.length,
itemBuilder: (BuildContext context, int index){
return
Text(
menuList[index],
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 40,
color: Colors.black,
),
);
},
),
),
);
},
// By default, show a loading spinner.
return CircularProgressIndicator();
},
}
Поскольку FutureBuilder
используется для асинхронной работы, то используйте hasData
, чтобы убедиться, что оно вводится snapshot.data.value["tt"].toString(),
после получения значения из базы данных.