flutter 如何让 gridview 像按钮一样显示 firebase 数据
flutter how to make gridview show firebase data like buttons
我正在尝试使用 Streambuilder 来显示 gridview,但是 return 这个错误,我正在调用方法 classList() 到脚手架主体中的容器
数据库=FirebaseDatabase.instance
我想在 gridview 中以 RaisedButtons
执行以下代码时出现此错误
I/flutter ( 5433): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 5433): The following NoSuchMethodError was thrown building HomePage(dirty, state: _HomePage#055be):
I/flutter ( 5433): The method 'split' was called on null.
I/flutter ( 5433): Receiver: null
I/flutter ( 5433): Tried calling: split("/")
I/flutter ( 5433):
I/flutter ( 5433): When the exception was thrown, this was the stack:
I/flutter ( 5433): #0 Object.noSuchMethod (dart:core/runtime/libobject_patch.dart:50:5)
I/flutter ( 5433): #1 DatabaseReference.child (file:///G:/flutter/.pub-cache/hosted/pub.dartlang.org/firebase_database-2.0.3/lib/src/database_reference.dart:24:58)
I/flutter ( 5433): #2 _HomePage.classList (package:barcode_scan_example/home_page.dart:169:44)
I/flutter ( 5433): #3 _HomePage.build (package:barcode_scan_example/home_page.dart:265:30)
I/flutter ( 5433): #4 StatefulElement.build (package:flutter/src/widgets/framework.dart:3825:27)
I/flutter ( 5433): #5 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3736:15)
I/flutter ( 5433): #6 Element.rebuild (package:flutter/src/widgets/framework.dart:3559:5)
I/flutter ( 5433): #7 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3716:5)
I/flutter ( 5433): #8 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3864:11)
I/flutter ( 5433): #9 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3711:5)
I/flutter ( 5433): #10 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2956:14)
I/flutter ( 5433): #11 Element.updateChild (package:flutter/src/widgets/framework.dart:2759:12)
I/flutter ( 5433): #12 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3747:16)
I/flutter ( 5433): #13 Element.rebuild (package:flutter/src/widgets/framework.dart:3559:5)
I/flutter ( 5433): #14 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2273:33)
I/flutter ( 5433): #15 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:700:20)
I/flutter ( 5433): #16 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:268:5)
I/flutter ( 5433): #17 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:988:15)
I/flutter ( 5433): #18 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:928:9)
I/flutter ( 5433): #19 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:840:5)
I/flutter ( 5433): #23 _invoke (dart:ui/hooks.dart:209:10)
I/flutter ( 5433): #24 _drawFrame (dart:ui/hooks.dart:168:3)
I/flutter ( 5433): (elided 3 frames from package dart:async)
classList() {
StreamBuilder(
stream:
database.reference().child('user').child(userUid).child('classData').orderByKey().onValue,
builder: (BuildContext context, AsyncSnapshot<Event> snapshot) {
if (snapshot.hasData) {
if (snapshot.data.snapshot.value != null) {
Map<dynamic, dynamic> map = snapshot.data.snapshot.value;
List<dynamic> list = map.values.toList();
print("list is : $list");
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3),
itemCount: list.length,
padding: EdgeInsets.all(2.0),
itemBuilder: (BuildContext context, int index) {
print("print job ${list[index]["className"]}");
return Container(
child: RaisedButton(
onPressed: null,
child: Text(
"${list[index]["className"]}\n ${list[index]["classSection"]}"),
),
padding: EdgeInsets.all(2.0),
);
},
);
} else {
return Container(
child: Center(
child: Text(
"There's no Class registered in the system",
style: TextStyle(fontSize: 20.0, color: Colors.grey),
textAlign: TextAlign.center,
)));
}
} else {
return CircularProgressIndicator();
}
});
}
整个飞镖文件
import 'package:flutter/material.dart';
import 'auth.dart';
import 'auth_provider.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/services.dart';
import 'make_class.dart';
import 'dart:async';
import 'package:barcode_scan/barcode_scan.dart';
import 'package:firebase_database/firebase_database.dart';
import 'qr_screen.dart';
class HomePage extends StatefulWidget {
@override
_HomePage createState() => _HomePage();
}
enum ScaffoldType { student, lecturer }
ScaffoldType _scaffoldType = ScaffoldType.lecturer;
class _HomePage extends State<HomePage> {
final FirebaseDatabase database = FirebaseDatabase.instance;
String barcode = "";
String userUid;
var userClass;
Future<void> _signOut(BuildContext context) async {
try {
final BaseAuth auth = AuthProvider.of(context).auth;
await auth.signOut();
} catch (e) {
print(e);
}
}
@override
void initState() {
super.initState();
userUi();
setState(() async* {
FirebaseDatabase database;
database = FirebaseDatabase.instance;
database.setPersistenceEnabled(true);
database.setPersistenceCacheSizeBytes(10000000);
});
}
Future reUser() async {
FirebaseUser user = await FirebaseAuth.instance.currentUser();
print(user.uid);
var userUid = user.uid;
var userWho = await database
.reference()
.child('user')
.child(userUid)
.once()
.then((DataSnapshot snapshot) {
Map<dynamic, dynamic> data = snapshot.value;
var isL = data.values.toList();
print(isL[1]);
print(data.values);
if (isL[1].toString().toLowerCase() == "true") {
_scaffoldType = ScaffoldType.lecturer;
print('lecturer');
} else if (isL[1].toString().toLowerCase() == "false") {
_scaffoldType = ScaffoldType.student;
print("student");
}
});
// print(userWho);
}
userUi() async {
FirebaseUser user = await FirebaseAuth.instance.currentUser();
print(user.uid);
return user.uid;
}
classList(userUid) {
print(userUid);
StreamBuilder(
stream:
database.reference().child('user').child(userUid).child('classData').orderByKey().onValue,
builder: (BuildContext context, AsyncSnapshot<Event> snapshot) {
if (snapshot.hasData) {
if (snapshot.data.snapshot.value != null) {
Map<dynamic, dynamic> map = snapshot.data.snapshot.value;
List<dynamic> list = map.values.toList();
print("list is : $list");
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3),
itemCount: list.length,
padding: EdgeInsets.all(2.0),
itemBuilder: (BuildContext context, int index) {
print("print job ${list[index]["className"]}");
return Container(
child: RaisedButton(
onPressed: (){},
child: Text(
"${list[index]["className"]}\n ${list[index]["classSection"]}"),
),
padding: EdgeInsets.all(2.0),
);
},
);
} else {
return Container(
child: Center(
child: Text(
"There's no Class registered in the system",
style: TextStyle(fontSize: 20.0, color: Colors.grey),
textAlign: TextAlign.center,
)));
}
} else {
return CircularProgressIndicator();
}
});
}
@override
Widget build(BuildContext context) {
// var userUid = userUi();
reUser();
return Scaffold(
appBar: AppBar(
title: Text('Welcome'),
actions: <Widget>[
FlatButton(
child: Icon(Icons.exit_to_app),
onPressed: () => _signOut(context),
)
],
),
bottomNavigationBar: BottomAppBar(
notchMargin: 8.0,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Padding(
padding: const EdgeInsets.fromLTRB(35, 0, 35, 0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: buttonBelow(),
),
Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: buttonBelow2(),
),
],
),
),
),
shape: CircularNotchedRectangle(),
),
resizeToAvoidBottomInset: true,
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: Container(
height: 80,
width: 80,
child: FittedBox(
child: FloatingActionButton(
onPressed: scan,
child: Icon(
Icons.camera,
size: 35,
),
elevation: 2.0,
),
),
),
body: Container(child: classList(userUi()),),
);
}
List<Widget> buttonBelow() {
if (_scaffoldType == ScaffoldType.lecturer) {
return <Widget>[
FlatButton(
child: Icon(
Icons.add_circle,
semanticLabel: "Add Class",
size: 45,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => MakeClass()),
);
},
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(180)),
),
Text("Add Class")
];
} else {
return <Widget>[
Opacity(
opacity: 0,
child: FlatButton(
onPressed: () {},
child: Icon(
Icons.add_circle,
semanticLabel: "Add Class",
size: 45,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(180)),
),
),
Opacity(opacity: 0, child: Text("Add Class"))
];
}
}
List<Widget> buttonBelow2() {
if (_scaffoldType == ScaffoldType.lecturer) {
return <Widget>[
FlatButton(
child: Icon(
Icons.blur_on,
semanticLabel: "QRCode",
size: 45,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => QrScreen()),
);
},
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(180)),
),
Text("QRCode")
];
}
}
Future scan() async {
try {
String barcode = await BarcodeScanner.scan();
setState(() => this.barcode = barcode);
} on PlatformException catch (e) {
if (e.code == BarcodeScanner.CameraAccessDenied) {
setState(() {
this.barcode = 'The user did not grant the camera permission!';
});
} else {
setState(() => this.barcode = 'Unknown error: $e');
}
} on FormatException {
setState(() => this.barcode =
'null (User returned using the "back"-button before scanning anything. Result)');
} catch (e) {
setState(() => this.barcode = 'Unknown error: $e');
}
}
}
主要问题是当我们在 firebase 的“.child()”方法中传递空白或空字符串时,它会给我们 split("/") 错误,因为在内部它会尝试从字符串中拆分并尝试获取数据
来自它。
现在您的代码中的问题是您在使用 StreamBuilder() 从 firebase userid 获取数据之前在小部件覆盖方法中调用 "classList(userUid)" 但 userUid 为空,正如我上面所说的,
如果我们在该“.child()”方法中传递空白或 null,firebase 将给我们 split("/") 错误。
所以结论是我们必须等待 firebase 用户标识,直到我们从异步结果中获取它,因为要获取 firebase 用户标识,这是异步任务,我们必须等待它,直到使用 await 关键字得到结果。
所以这是答案,如何做到这一点:
您必须使用 future<> 替换小部件中的正文部分,如下所示:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Welcome'),
actions: <Widget>[
FlatButton(
child: Icon(Icons.exit_to_app),
onPressed: () => _signOut(context),
)
],
),
bottomNavigationBar: BottomAppBar(
notchMargin: 8.0,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Padding(
padding: const EdgeInsets.fromLTRB(35, 0, 35, 0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: buttonBelow(),
),
Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: buttonBelow2(),
),
],
),
),
),
shape: CircularNotchedRectangle(),
),
resizeToAvoidBottomInset: true,
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: Container(
height: 80,
width: 80,
child: FittedBox(
child: FloatingActionButton(
onPressed: scan,
child: Icon(
Icons.camera,
size: 35,
),
elevation: 2.0,
),
),
),
body: new FutureBuilder<FirebaseUser>(
future: FirebaseAuth.instance.currentUser(),
builder: (BuildContext context, AsyncSnapshot<FirebaseUser> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return new Container(child: classList(snapshot.data.uid));
}
else {
return new Text('Loading...');
}
},
),
);
}
此外,最佳做法是您必须仅在 "initState()" 方法中获取 firebase 用户 ID,该方法在生命周期内仅调用一次。所以在你的 class 中全局声明 "FirebaseUser user" 然后调用你的 "userUi()"
仅在 "initState()" 方法中。
The method 'split' was called on null.
每当您引用不存在的路径时,就会发生这种类型的异常。所以请确保你的 firebase 数据库的路径是正确的。
我正在尝试使用 Streambuilder 来显示 gridview,但是 return 这个错误,我正在调用方法 classList() 到脚手架主体中的容器
数据库=FirebaseDatabase.instance
我想在 gridview 中以 RaisedButtons
执行以下代码时出现此错误
I/flutter ( 5433): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 5433): The following NoSuchMethodError was thrown building HomePage(dirty, state: _HomePage#055be):
I/flutter ( 5433): The method 'split' was called on null.
I/flutter ( 5433): Receiver: null
I/flutter ( 5433): Tried calling: split("/")
I/flutter ( 5433):
I/flutter ( 5433): When the exception was thrown, this was the stack:
I/flutter ( 5433): #0 Object.noSuchMethod (dart:core/runtime/libobject_patch.dart:50:5)
I/flutter ( 5433): #1 DatabaseReference.child (file:///G:/flutter/.pub-cache/hosted/pub.dartlang.org/firebase_database-2.0.3/lib/src/database_reference.dart:24:58)
I/flutter ( 5433): #2 _HomePage.classList (package:barcode_scan_example/home_page.dart:169:44)
I/flutter ( 5433): #3 _HomePage.build (package:barcode_scan_example/home_page.dart:265:30)
I/flutter ( 5433): #4 StatefulElement.build (package:flutter/src/widgets/framework.dart:3825:27)
I/flutter ( 5433): #5 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3736:15)
I/flutter ( 5433): #6 Element.rebuild (package:flutter/src/widgets/framework.dart:3559:5)
I/flutter ( 5433): #7 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3716:5)
I/flutter ( 5433): #8 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3864:11)
I/flutter ( 5433): #9 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3711:5)
I/flutter ( 5433): #10 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2956:14)
I/flutter ( 5433): #11 Element.updateChild (package:flutter/src/widgets/framework.dart:2759:12)
I/flutter ( 5433): #12 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3747:16)
I/flutter ( 5433): #13 Element.rebuild (package:flutter/src/widgets/framework.dart:3559:5)
I/flutter ( 5433): #14 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2273:33)
I/flutter ( 5433): #15 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:700:20)
I/flutter ( 5433): #16 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:268:5)
I/flutter ( 5433): #17 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:988:15)
I/flutter ( 5433): #18 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:928:9)
I/flutter ( 5433): #19 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:840:5)
I/flutter ( 5433): #23 _invoke (dart:ui/hooks.dart:209:10)
I/flutter ( 5433): #24 _drawFrame (dart:ui/hooks.dart:168:3)
I/flutter ( 5433): (elided 3 frames from package dart:async)
classList() {
StreamBuilder(
stream:
database.reference().child('user').child(userUid).child('classData').orderByKey().onValue,
builder: (BuildContext context, AsyncSnapshot<Event> snapshot) {
if (snapshot.hasData) {
if (snapshot.data.snapshot.value != null) {
Map<dynamic, dynamic> map = snapshot.data.snapshot.value;
List<dynamic> list = map.values.toList();
print("list is : $list");
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3),
itemCount: list.length,
padding: EdgeInsets.all(2.0),
itemBuilder: (BuildContext context, int index) {
print("print job ${list[index]["className"]}");
return Container(
child: RaisedButton(
onPressed: null,
child: Text(
"${list[index]["className"]}\n ${list[index]["classSection"]}"),
),
padding: EdgeInsets.all(2.0),
);
},
);
} else {
return Container(
child: Center(
child: Text(
"There's no Class registered in the system",
style: TextStyle(fontSize: 20.0, color: Colors.grey),
textAlign: TextAlign.center,
)));
}
} else {
return CircularProgressIndicator();
}
});
}
整个飞镖文件
import 'package:flutter/material.dart';
import 'auth.dart';
import 'auth_provider.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/services.dart';
import 'make_class.dart';
import 'dart:async';
import 'package:barcode_scan/barcode_scan.dart';
import 'package:firebase_database/firebase_database.dart';
import 'qr_screen.dart';
class HomePage extends StatefulWidget {
@override
_HomePage createState() => _HomePage();
}
enum ScaffoldType { student, lecturer }
ScaffoldType _scaffoldType = ScaffoldType.lecturer;
class _HomePage extends State<HomePage> {
final FirebaseDatabase database = FirebaseDatabase.instance;
String barcode = "";
String userUid;
var userClass;
Future<void> _signOut(BuildContext context) async {
try {
final BaseAuth auth = AuthProvider.of(context).auth;
await auth.signOut();
} catch (e) {
print(e);
}
}
@override
void initState() {
super.initState();
userUi();
setState(() async* {
FirebaseDatabase database;
database = FirebaseDatabase.instance;
database.setPersistenceEnabled(true);
database.setPersistenceCacheSizeBytes(10000000);
});
}
Future reUser() async {
FirebaseUser user = await FirebaseAuth.instance.currentUser();
print(user.uid);
var userUid = user.uid;
var userWho = await database
.reference()
.child('user')
.child(userUid)
.once()
.then((DataSnapshot snapshot) {
Map<dynamic, dynamic> data = snapshot.value;
var isL = data.values.toList();
print(isL[1]);
print(data.values);
if (isL[1].toString().toLowerCase() == "true") {
_scaffoldType = ScaffoldType.lecturer;
print('lecturer');
} else if (isL[1].toString().toLowerCase() == "false") {
_scaffoldType = ScaffoldType.student;
print("student");
}
});
// print(userWho);
}
userUi() async {
FirebaseUser user = await FirebaseAuth.instance.currentUser();
print(user.uid);
return user.uid;
}
classList(userUid) {
print(userUid);
StreamBuilder(
stream:
database.reference().child('user').child(userUid).child('classData').orderByKey().onValue,
builder: (BuildContext context, AsyncSnapshot<Event> snapshot) {
if (snapshot.hasData) {
if (snapshot.data.snapshot.value != null) {
Map<dynamic, dynamic> map = snapshot.data.snapshot.value;
List<dynamic> list = map.values.toList();
print("list is : $list");
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3),
itemCount: list.length,
padding: EdgeInsets.all(2.0),
itemBuilder: (BuildContext context, int index) {
print("print job ${list[index]["className"]}");
return Container(
child: RaisedButton(
onPressed: (){},
child: Text(
"${list[index]["className"]}\n ${list[index]["classSection"]}"),
),
padding: EdgeInsets.all(2.0),
);
},
);
} else {
return Container(
child: Center(
child: Text(
"There's no Class registered in the system",
style: TextStyle(fontSize: 20.0, color: Colors.grey),
textAlign: TextAlign.center,
)));
}
} else {
return CircularProgressIndicator();
}
});
}
@override
Widget build(BuildContext context) {
// var userUid = userUi();
reUser();
return Scaffold(
appBar: AppBar(
title: Text('Welcome'),
actions: <Widget>[
FlatButton(
child: Icon(Icons.exit_to_app),
onPressed: () => _signOut(context),
)
],
),
bottomNavigationBar: BottomAppBar(
notchMargin: 8.0,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Padding(
padding: const EdgeInsets.fromLTRB(35, 0, 35, 0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: buttonBelow(),
),
Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: buttonBelow2(),
),
],
),
),
),
shape: CircularNotchedRectangle(),
),
resizeToAvoidBottomInset: true,
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: Container(
height: 80,
width: 80,
child: FittedBox(
child: FloatingActionButton(
onPressed: scan,
child: Icon(
Icons.camera,
size: 35,
),
elevation: 2.0,
),
),
),
body: Container(child: classList(userUi()),),
);
}
List<Widget> buttonBelow() {
if (_scaffoldType == ScaffoldType.lecturer) {
return <Widget>[
FlatButton(
child: Icon(
Icons.add_circle,
semanticLabel: "Add Class",
size: 45,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => MakeClass()),
);
},
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(180)),
),
Text("Add Class")
];
} else {
return <Widget>[
Opacity(
opacity: 0,
child: FlatButton(
onPressed: () {},
child: Icon(
Icons.add_circle,
semanticLabel: "Add Class",
size: 45,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(180)),
),
),
Opacity(opacity: 0, child: Text("Add Class"))
];
}
}
List<Widget> buttonBelow2() {
if (_scaffoldType == ScaffoldType.lecturer) {
return <Widget>[
FlatButton(
child: Icon(
Icons.blur_on,
semanticLabel: "QRCode",
size: 45,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => QrScreen()),
);
},
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(180)),
),
Text("QRCode")
];
}
}
Future scan() async {
try {
String barcode = await BarcodeScanner.scan();
setState(() => this.barcode = barcode);
} on PlatformException catch (e) {
if (e.code == BarcodeScanner.CameraAccessDenied) {
setState(() {
this.barcode = 'The user did not grant the camera permission!';
});
} else {
setState(() => this.barcode = 'Unknown error: $e');
}
} on FormatException {
setState(() => this.barcode =
'null (User returned using the "back"-button before scanning anything. Result)');
} catch (e) {
setState(() => this.barcode = 'Unknown error: $e');
}
}
}
主要问题是当我们在 firebase 的“.child()”方法中传递空白或空字符串时,它会给我们 split("/") 错误,因为在内部它会尝试从字符串中拆分并尝试获取数据 来自它。
现在您的代码中的问题是您在使用 StreamBuilder() 从 firebase userid 获取数据之前在小部件覆盖方法中调用 "classList(userUid)" 但 userUid 为空,正如我上面所说的, 如果我们在该“.child()”方法中传递空白或 null,firebase 将给我们 split("/") 错误。
所以结论是我们必须等待 firebase 用户标识,直到我们从异步结果中获取它,因为要获取 firebase 用户标识,这是异步任务,我们必须等待它,直到使用 await 关键字得到结果。
所以这是答案,如何做到这一点: 您必须使用 future<> 替换小部件中的正文部分,如下所示:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Welcome'),
actions: <Widget>[
FlatButton(
child: Icon(Icons.exit_to_app),
onPressed: () => _signOut(context),
)
],
),
bottomNavigationBar: BottomAppBar(
notchMargin: 8.0,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Padding(
padding: const EdgeInsets.fromLTRB(35, 0, 35, 0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: buttonBelow(),
),
Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: buttonBelow2(),
),
],
),
),
),
shape: CircularNotchedRectangle(),
),
resizeToAvoidBottomInset: true,
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: Container(
height: 80,
width: 80,
child: FittedBox(
child: FloatingActionButton(
onPressed: scan,
child: Icon(
Icons.camera,
size: 35,
),
elevation: 2.0,
),
),
),
body: new FutureBuilder<FirebaseUser>(
future: FirebaseAuth.instance.currentUser(),
builder: (BuildContext context, AsyncSnapshot<FirebaseUser> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return new Container(child: classList(snapshot.data.uid));
}
else {
return new Text('Loading...');
}
},
),
);
}
此外,最佳做法是您必须仅在 "initState()" 方法中获取 firebase 用户 ID,该方法在生命周期内仅调用一次。所以在你的 class 中全局声明 "FirebaseUser user" 然后调用你的 "userUi()" 仅在 "initState()" 方法中。
The method 'split' was called on null.
每当您引用不存在的路径时,就会发生这种类型的异常。所以请确保你的 firebase 数据库的路径是正确的。