使用 firebase 在 flutter 中构建聊天屏幕时出错
error in building chat screen in flutter using firebase
大家好,
我正在学习使用 firebase 在 flutter 应用程序中进行聊天,我得到了一段代码来理解它的工作原理,但它显示错误,我无法很好地理解代码。
下面是显示错误的屏幕 -:
import 'dart:async';
import 'dart:io';
import 'dart:core';
import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_database/ui/firebase_animated_list.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_chat_app/widget/ChatMessageListItem.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:image_picker/image_picker.dart';
final googleSignIn = new GoogleSignIn();
final analytics = new FirebaseAnalytics();
final auth = FirebaseAuth.instance;
var currentUserEmail;
var _scaffoldContext;
class ChatScreen extends StatefulWidget {
@override
ChatScreenState createState() {
return new ChatScreenState();
}
}
class ChatScreenState extends State<ChatScreen> {
final TextEditingController _textEditingController =
new TextEditingController();
bool _isComposingMessage = false;
final reference = FirebaseDatabase.instance.reference().child('messages');
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Flutter Chat App"),
elevation:
Theme.of(context).platform == TargetPlatform.iOS ? 0.0 : 4.0,
actions: <Widget>[
new IconButton(
icon: new Icon(Icons.exit_to_app), onPressed: _signOut)
],
),
body: new Container(
child: new Column(
children: <Widget>[
new Flexible(
child: new FirebaseAnimatedList(
query: reference,
padding: const EdgeInsets.all(8.0),
reverse: true,
sort: (a, b) => b.key.compareTo(a.key),
//comparing timestamp of messages to check which one would appear first
// this itembuilder is showing error
itemBuilder: (_,DataSnapshot messageSnapshot, Animation<double> animation){
return new ChatMessageListItem(
messageSnapshot: messageSnapshot,
animation: animation,
);
},
),
),
new Divider(height: 1.0),
new Container(
decoration:
new BoxDecoration(color: Theme.of(context).cardColor),
child: _buildTextComposer(),
),
new Builder(builder: (BuildContext context) {
_scaffoldContext = context;
return new Container(width: 0.0, height: 0.0);
}),
],
),
decoration: Theme.of(context).platform == TargetPlatform.iOS
? new BoxDecoration(
border: new Border(
top: new BorderSide(
color: Colors.grey[200],
)))
: null,
),
);
}
CupertinoButton getIOSSendButton() {
return new CupertinoButton(
child: new Text("Send"),
onPressed: _isComposingMessage
? () => _textMessageSubmitted(_textEditingController.text)
: null,
);
}
IconButton getDefaultSendButton() {
return new IconButton(
icon: new Icon(Icons.send),
onPressed: _isComposingMessage
? () => _textMessageSubmitted(_textEditingController.text)
: null,
);
}
Widget _buildTextComposer() {
return new IconTheme(
data: new IconThemeData(
color: _isComposingMessage
? Theme.of(context).accentColor
: Theme.of(context).disabledColor,
),
child: new Container(
margin: const EdgeInsets.symmetric(horizontal: 8.0),
child: new Row(
children: <Widget>[
new Container(
margin: new EdgeInsets.symmetric(horizontal: 4.0),
child: new IconButton(
icon: new Icon(
Icons.photo_camera,
color: Theme.of(context).accentColor,
),
onPressed: () async {
await _ensureLoggedIn();
File imageFile = await ImagePicker.pickImage();
int timestamp = new DateTime.now().millisecondsSinceEpoch;
Reference storageReference = FirebaseStorage
.instance
.ref()
.child("img_" + timestamp.toString() + ".jpg");
var uploadTask =
storageReference.putFile(imageFile);
// this downloadUrl is also showing an error
Uri downloadUrl = (uploadTask.snapshotEvents).downloadUrl;
_sendMessage(
messageText: null, imageUrl: downloadUrl.toString());
}
),
),
new Flexible(
child: new TextField(
controller: _textEditingController,
onChanged: (String messageText) {
setState(() {
_isComposingMessage = messageText.length > 0;
});
},
onSubmitted: _textMessageSubmitted,
decoration:
new InputDecoration.collapsed(hintText: "Send a message"),
),
),
new Container(
margin: const EdgeInsets.symmetric(horizontal: 4.0),
child: Theme.of(context).platform == TargetPlatform.iOS
? getIOSSendButton()
: getDefaultSendButton(),
),
],
),
));
}
Future<Null> _textMessageSubmitted(String text) async {
_textEditingController.clear();
setState(() {
_isComposingMessage = false;
});
await _ensureLoggedIn();
_sendMessage(messageText: text, imageUrl: null);
}
void _sendMessage({String messageText, String imageUrl}) {
reference.push().set({
'text': messageText,
'email': googleSignIn.currentUser.email,
'imageUrl': imageUrl,
'senderName': googleSignIn.currentUser.displayName,
'senderPhotoUrl': googleSignIn.currentUser.photoUrl,
});
analytics.logEvent(name: 'send_message');
}
Future<Null> _ensureLoggedIn() async {
GoogleSignInAccount signedInUser = googleSignIn.currentUser;
if (signedInUser == null)
signedInUser = await googleSignIn.signInSilently();
if (signedInUser == null) {
await googleSignIn.signIn();
analytics.logLogin();
}
currentUserEmail = googleSignIn.currentUser.email;
if (await auth.currentUser == null) {
GoogleSignInAuthentication credentials =
await googleSignIn.currentUser.authentication;
// here sign in with google is also showing error.
await auth.signInWithGoogle(
idToken: credentials.idToken, accessToken: credentials.accessToken);
}
}
Future _signOut() async {
await auth.signOut();
googleSignIn.signOut();
Scaffold
.of(_scaffoldContext)
.showSnackBar(new SnackBar(content: new Text('User logged out')));
}
}
我已经在评论中指出了哪部分显示错误。如果有人能帮我解决这个问题,那就太好了。
谢谢。
下面是错误-:
第二个错误-:
第三个错误-:
FirebaseAnimatedList
的itemBuilder
函数接受4个参数,但你只给了它3个。
简单的解决方法是添加另一个参数,它需要是 int
.
itemBuilder: (_,DataSnapshot messageSnapshot, Animation<double> animation, int yourVariableName)
{
// Put your code here
}
大家好, 我正在学习使用 firebase 在 flutter 应用程序中进行聊天,我得到了一段代码来理解它的工作原理,但它显示错误,我无法很好地理解代码。 下面是显示错误的屏幕 -:
import 'dart:async';
import 'dart:io';
import 'dart:core';
import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_database/ui/firebase_animated_list.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_chat_app/widget/ChatMessageListItem.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:image_picker/image_picker.dart';
final googleSignIn = new GoogleSignIn();
final analytics = new FirebaseAnalytics();
final auth = FirebaseAuth.instance;
var currentUserEmail;
var _scaffoldContext;
class ChatScreen extends StatefulWidget {
@override
ChatScreenState createState() {
return new ChatScreenState();
}
}
class ChatScreenState extends State<ChatScreen> {
final TextEditingController _textEditingController =
new TextEditingController();
bool _isComposingMessage = false;
final reference = FirebaseDatabase.instance.reference().child('messages');
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Flutter Chat App"),
elevation:
Theme.of(context).platform == TargetPlatform.iOS ? 0.0 : 4.0,
actions: <Widget>[
new IconButton(
icon: new Icon(Icons.exit_to_app), onPressed: _signOut)
],
),
body: new Container(
child: new Column(
children: <Widget>[
new Flexible(
child: new FirebaseAnimatedList(
query: reference,
padding: const EdgeInsets.all(8.0),
reverse: true,
sort: (a, b) => b.key.compareTo(a.key),
//comparing timestamp of messages to check which one would appear first
// this itembuilder is showing error
itemBuilder: (_,DataSnapshot messageSnapshot, Animation<double> animation){
return new ChatMessageListItem(
messageSnapshot: messageSnapshot,
animation: animation,
);
},
),
),
new Divider(height: 1.0),
new Container(
decoration:
new BoxDecoration(color: Theme.of(context).cardColor),
child: _buildTextComposer(),
),
new Builder(builder: (BuildContext context) {
_scaffoldContext = context;
return new Container(width: 0.0, height: 0.0);
}),
],
),
decoration: Theme.of(context).platform == TargetPlatform.iOS
? new BoxDecoration(
border: new Border(
top: new BorderSide(
color: Colors.grey[200],
)))
: null,
),
);
}
CupertinoButton getIOSSendButton() {
return new CupertinoButton(
child: new Text("Send"),
onPressed: _isComposingMessage
? () => _textMessageSubmitted(_textEditingController.text)
: null,
);
}
IconButton getDefaultSendButton() {
return new IconButton(
icon: new Icon(Icons.send),
onPressed: _isComposingMessage
? () => _textMessageSubmitted(_textEditingController.text)
: null,
);
}
Widget _buildTextComposer() {
return new IconTheme(
data: new IconThemeData(
color: _isComposingMessage
? Theme.of(context).accentColor
: Theme.of(context).disabledColor,
),
child: new Container(
margin: const EdgeInsets.symmetric(horizontal: 8.0),
child: new Row(
children: <Widget>[
new Container(
margin: new EdgeInsets.symmetric(horizontal: 4.0),
child: new IconButton(
icon: new Icon(
Icons.photo_camera,
color: Theme.of(context).accentColor,
),
onPressed: () async {
await _ensureLoggedIn();
File imageFile = await ImagePicker.pickImage();
int timestamp = new DateTime.now().millisecondsSinceEpoch;
Reference storageReference = FirebaseStorage
.instance
.ref()
.child("img_" + timestamp.toString() + ".jpg");
var uploadTask =
storageReference.putFile(imageFile);
// this downloadUrl is also showing an error
Uri downloadUrl = (uploadTask.snapshotEvents).downloadUrl;
_sendMessage(
messageText: null, imageUrl: downloadUrl.toString());
}
),
),
new Flexible(
child: new TextField(
controller: _textEditingController,
onChanged: (String messageText) {
setState(() {
_isComposingMessage = messageText.length > 0;
});
},
onSubmitted: _textMessageSubmitted,
decoration:
new InputDecoration.collapsed(hintText: "Send a message"),
),
),
new Container(
margin: const EdgeInsets.symmetric(horizontal: 4.0),
child: Theme.of(context).platform == TargetPlatform.iOS
? getIOSSendButton()
: getDefaultSendButton(),
),
],
),
));
}
Future<Null> _textMessageSubmitted(String text) async {
_textEditingController.clear();
setState(() {
_isComposingMessage = false;
});
await _ensureLoggedIn();
_sendMessage(messageText: text, imageUrl: null);
}
void _sendMessage({String messageText, String imageUrl}) {
reference.push().set({
'text': messageText,
'email': googleSignIn.currentUser.email,
'imageUrl': imageUrl,
'senderName': googleSignIn.currentUser.displayName,
'senderPhotoUrl': googleSignIn.currentUser.photoUrl,
});
analytics.logEvent(name: 'send_message');
}
Future<Null> _ensureLoggedIn() async {
GoogleSignInAccount signedInUser = googleSignIn.currentUser;
if (signedInUser == null)
signedInUser = await googleSignIn.signInSilently();
if (signedInUser == null) {
await googleSignIn.signIn();
analytics.logLogin();
}
currentUserEmail = googleSignIn.currentUser.email;
if (await auth.currentUser == null) {
GoogleSignInAuthentication credentials =
await googleSignIn.currentUser.authentication;
// here sign in with google is also showing error.
await auth.signInWithGoogle(
idToken: credentials.idToken, accessToken: credentials.accessToken);
}
}
Future _signOut() async {
await auth.signOut();
googleSignIn.signOut();
Scaffold
.of(_scaffoldContext)
.showSnackBar(new SnackBar(content: new Text('User logged out')));
}
}
我已经在评论中指出了哪部分显示错误。如果有人能帮我解决这个问题,那就太好了。 谢谢。
下面是错误-:
第二个错误-:
第三个错误-:
FirebaseAnimatedList
的itemBuilder
函数接受4个参数,但你只给了它3个。
简单的解决方法是添加另一个参数,它需要是 int
.
itemBuilder: (_,DataSnapshot messageSnapshot, Animation<double> animation, int yourVariableName)
{
// Put your code here
}