【发布时间】:2020-11-30 17:54:59
【问题描述】:
我正在将图片上传到 Firebase 存储,然后将链接保存到 Firebase 数据库中。 我创建了一个流来监听数据库中的变化,所以每次上传新图像时,它都会显示在应用程序中。
但每次我运行应用程序时都会出现错误,并且应用程序崩溃。 (如此处所示:https://prnt.sc/txj3jc)。
Flutter 医生:https://prnt.sc/txj5q8.
代码:
import 'package:flutter/material.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/widgets.dart';
import 'dart:io';
import 'package:image_picker/image_picker.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
final _firestore = Firestore.instance;
int pictureNumber = 0;
List<Widget> pictures = [];
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark(),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
var _scaffoldKey = GlobalKey<ScaffoldState>();
String imageLink;
File _image;
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.blue,
child: Icon(
Icons.add,
size: 30,
),
onPressed: () async {
_image =
// ignore: deprecated_member_use
await ImagePicker.pickImage(source: ImageSource.gallery);
FirebaseStorage firebaseStorage = FirebaseStorage.instance;
StorageReference rootReference = firebaseStorage.ref();
StorageReference pictureFolderRef =
rootReference.child('pictures').child('$pictureNumber');
pictureFolderRef.putFile(_image).onComplete.then((storageTask) async {
String link = await storageTask.ref.getDownloadURL();
await _firestore
.collection('links')
.add({'link': link, 'index': pictureNumber});
setState(() {
pictures.add(Image.network('$link'));
print(link);
_firestore.collection('links').orderBy('index');
});
pictureNumber++;
// setState(() {
// imageLink = link;
// pictures.add(
// Image.network('$imageLink'),
// );
// print(pictures.length);
// });
});
},
),
// body: Container(
// width: double.infinity,
// child: Column(
// children: [
// Expanded(
// child: ListView.builder(
// itemCount: pictures.length,
// itemBuilder: (context, index) => Padding(
// padding: EdgeInsets.all(16.0),
// child: pictures[index],
// ),
// )),
// ],
// ),
// ),
key: _scaffoldKey,
body: PictureStream(),
);
}
}
class PictureStream extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: _firestore.collection('links').snapshots(),
// ignore: missing_return
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(
backgroundColor: Color(0xFF3E3E3E),
),
);
}
final links = snapshot.data;
for (var linkData in links) {
final index = linkData.data['index'];
final link = linkData.data['link'];
pictures.add(Image.network(link));
}
return Container(
width: double.infinity,
child: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: pictures.length,
itemBuilder: (context, index) => Padding(
padding: EdgeInsets.all(16.0),
child: pictures[index],
),
)),
],
),
);
},
);
}
}
错误:
Performing hot restart...
Syncing files to device SM A205F...
Restarted application in 3,046ms.
D/SurfaceView( 8984): onWindowVisibilityChanged(4) false io.flutter.embedding.android.FlutterSurfaceView{99c7814 V.E...... ........ 0,0-720,1560} of ViewRootImpl@c270626[MainActivity]
D/ViewRootImpl@c270626[MainActivity]( 8984): Relayout returned: old=(0,0,720,1560) new=(0,0,720,1560) req=(720,1560)4 dur=11 res=0x1 s={false 0} ch=false
D/ViewRootImpl@c270626[MainActivity]( 8984): stopped(false) old=true
D/SurfaceView( 8984): windowStopped(false) false io.flutter.embedding.android.FlutterSurfaceView{99c7814 V.E...... ........ 0,0-720,1560} of ViewRootImpl@c270626[MainActivity]
D/ViewRootImpl@c270626[MainActivity]( 8984): stopped(false) old=false
D/SurfaceView( 8984): onWindowVisibilityChanged(0) true io.flutter.embedding.android.FlutterSurfaceView{99c7814 V.E...... ........ 0,0-720,1560} of ViewRootImpl@c270626[MainActivity]
D/ViewRootImpl@c270626[MainActivity]( 8984): Relayout returned: old=(0,0,720,1560) new=(0,0,720,1560) req=(720,1560)0 dur=15 res=0x7 s={true 515117469696} ch=true
D/OpenGLRenderer( 8984): createReliableSurface : 0x77f381c840, 0x77ef64d000
D/mali_winsys( 8984): EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, EGLBoolean) returns 0x3000
D/SurfaceView( 8984): surfaceCreated 1 #8 io.flutter.embedding.android.FlutterSurfaceView{99c7814 V.E...... ........ 0,0-720,1560}
D/mali_winsys( 8984): EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, EGLBoolean) returns 0x3000
D/SurfaceView( 8984): surfaceChanged (720,1560) 1 #8 io.flutter.embedding.android.FlutterSurfaceView{99c7814 V.E...... ........ 0,0-720,1560}
D/ViewRootImpl@c270626[MainActivity]( 8984): MSG_WINDOW_FOCUS_CHANGED 1 1
D/InputMethodManager( 8984): prepareNavigationBarInfo() DecorView@2fcf57c[MainActivity]
D/InputMethodManager( 8984): getNavigationBarColor() -855310
D/InputMethodManager( 8984): prepareNavigationBarInfo() DecorView@2fcf57c[MainActivity]
D/InputMethodManager( 8984): getNavigationBarColor() -855310
V/InputMethodManager( 8984): Starting input: tba=menachemmaron14082004.image_firebase ic=null mNaviBarColor -855310 mIsGetNaviBarColorSuccess true , NavVisible : true , NavTrans : false
D/InputMethodManager( 8984): startInputInner - Id : 0
I/InputMethodManager( 8984): startInputInner - mService.startInputOrWindowGainedFocus
I/flutter ( 8984): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 8984): The following _TypeError was thrown building StreamBuilder<QuerySnapshot>(dirty, state:
I/flutter ( 8984): _StreamBuilderBaseState<QuerySnapshot, AsyncSnapshot<QuerySnapshot>>#3e08b):
I/flutter ( 8984): type 'QuerySnapshot' is not a subtype of type 'Iterable<dynamic>'
I/flutter ( 8984):
I/flutter ( 8984): The relevant error-causing widget was:
I/flutter ( 8984): StreamBuilder<QuerySnapshot>
I/flutter ( 8984): file:///C:/Users/menac/AndroidStudioProjects/image_firebase/lib/main.dart:99:12
I/flutter ( 8984):
I/flutter ( 8984): When the exception was thrown, this was the stack:
I/flutter ( 8984): #0 PictureStream.build.<anonymous closure> (package:image_firebase/main.dart:111:30)
I/flutter ( 8984): #1 StreamBuilder.build (package:flutter/src/widgets/async.dart:509:81)
I/flutter ( 8984): #2 _StreamBuilderBaseState.build (package:flutter/src/widgets/async.dart:127:48)
I/flutter ( 8984): #3 StatefulElement.build (package:flutter/src/widgets/framework.dart:4623:28)
I/flutter ( 8984): #4 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4506:15)
I/flutter ( 8984): #5 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4679:11)
I/flutter ( 8984): #6 Element.rebuild (package:flutter/src/widgets/framework.dart:4222:5)
I/flutter ( 8984): #7 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2627:33)
I/flutter ( 8984): #8 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:864:20)
I/flutter ( 8984): #9 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:284:5)
I/flutter ( 8984): #10 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1074:15)
I/flutter ( 8984): #11 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1013:9)
I/flutter ( 8984): #12 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:929:5)
I/flutter ( 8984): #16 _invoke (dart:ui/hooks.dart:277:10)
I/flutter ( 8984): #17 _drawFrame (dart:ui/hooks.dart:235:3)
I/flutter ( 8984): (elided 3 frames from dart:async)
I/flutter ( 8984):
I/flutter ( 8984): ════════════════════════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following _TypeError was thrown building StreamBuilder<QuerySnapshot>(dirty, state: _StreamBuilderBaseState<QuerySnapshot, AsyncSnapshot<QuerySnapshot>>#3e08b):
type 'QuerySnapshot' is not a subtype of type 'Iterable<dynamic>'
The relevant error-causing widget was:
StreamBuilder<QuerySnapshot> file:///C:/Users/menac/AndroidStudioProjects/image_firebase/lib/main.dart:99:12
When the exception was thrown, this was the stack:
#0 PictureStream.build.<anonymous closure> (package:image_firebase/main.dart:111:30)
#1 StreamBuilder.build (package:flutter/src/widgets/async.dart:509:81)
#2 _StreamBuilderBaseState.build (package:flutter/src/widgets/async.dart:127:48)
#3 StatefulElement.build (package:flutter/src/widgets/framework.dart:4623:28)
#4 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4506:15)
...
════════════════════════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
type 'QuerySnapshot' is not a subtype of type 'Iterable<dynamic>'
The relevant error-causing widget was:
StreamBuilder<QuerySnapshot> file:///C:/Users/menac/AndroidStudioProjects/image_firebase/lib/main.dart:99:12
════════════════════════════════════════════════════════════════════════════════════════════════════
我是 Flutter 的新手,如果这是一个愚蠢的错误,请见谅。
编辑: 问题的第一部分已经解决了,但现在还有一个问题,它会多次显示每张图像,而不是只显示一次。
代码:
import 'package:flutter/material.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/widgets.dart';
import 'dart:io';
import 'package:image_picker/image_picker.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
final _firestore = Firestore.instance;
int pictureNumber = 0;
List<Widget> pictures = [];
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark(),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
var _scaffoldKey = GlobalKey<ScaffoldState>();
String imageLink;
File _image;
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.blue,
child: Icon(
Icons.add,
size: 30,
),
onPressed: () async {
_image =
// ignore: deprecated_member_use
await ImagePicker.pickImage(source: ImageSource.gallery);
FirebaseStorage firebaseStorage = FirebaseStorage.instance;
StorageReference rootReference = firebaseStorage.ref();
StorageReference pictureFolderRef =
rootReference.child('pictures').child('$pictureNumber');
pictureFolderRef.putFile(_image).onComplete.then((storageTask) async {
String link = await storageTask.ref.getDownloadURL();
await _firestore
.collection('links')
.add({'link': link, 'index': pictureNumber});
setState(() {
pictureNumber++;
pictures.add(Image.network('$link'));
print(link);
_firestore.collection('links').orderBy('index');
});
print(pictures.length);
// setState(() {
// imageLink = link;
// pictures.add(
// Image.network('$imageLink'),
// );
// print(pictures.length);
// });
});
},
),
// body: Container(
// width: double.infinity,
// child: Column(
// children: [
// Expanded(
// child: ListView.builder(
// itemCount: pictures.length,
// itemBuilder: (context, index) => Padding(
// padding: EdgeInsets.all(16.0),
// child: pictures[index],
// ),
// )),
// ],
// ),
// ),
key: _scaffoldKey,
body: PictureStream(),
);
}
}
class PictureStream extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: _firestore.collection('links').orderBy('link').snapshots(),
// ignore: missing_return
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(
backgroundColor: Color(0xFF3E3E3E),
),
);
}
final links = snapshot.data.documents;
for (var linkData in links) {
final index = linkData.data['index'];
final link = linkData.data['link'];
print(link);
print(index);
pictures.add(Image.network(link));
print(pictures.length);
}
return Container(
width: double.infinity,
child: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: pictures.length,
itemBuilder: (context, index) => Padding(
padding: EdgeInsets.all(16.0),
child: pictures[index],
),
)),
],
),
);
},
);
}
}
Firebase 存储 - https://prnt.sc/txy8ag Firebase 数据库 - https://prnt.sc/txya16
它按索引顺序显示所有 3 张图片 - 3 次,总共 9 张图片显示在应用程序上。
【问题讨论】:
标签: android firebase android-studio flutter google-cloud-firestore