【发布时间】:2021-09-17 16:20:16
【问题描述】:
我正在尝试构建一个社交应用程序,我将在其中发布图像。当我运行代码时,我在从 firebase 检索数据时遇到了一些问题。
firebase_auth: ^3.1.1
firebase_core: ^1.6.0
google_sign_in: ^5.1.0
firebase_storage: ^10.0.3
cloud_firestore: ^2.5.3
firebase_analytics: ^8.3.2
lottie: ^1.1.0
image_picker: ^0.8.4
上面是pubspec.yaml文件的依赖。
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
int _currentIndex = 0;
final List<Widget> _children = [
WeCareHomeScreen(),
WeCareReminder(),
Feed(),
Chatroom(),
Profile(),
];
@override
void initState() {
super.initState();
Provider.of<FirebaseOperations>(context, listen: false)
.initUserData(context)
.whenComplete(() {
setState(() {});
});
}
Widget build(BuildContext context) {
return Scaffold(
body: _children[_currentIndex],
bottomNavigationBar: CurvedNavigationBar(
index: 0,
height: 50.0,
items: <Widget>[
Icon(
Icons.home,
size: 25,
color: Colors.white,
),
Icon(
Icons.home,
size: 25,
color: Colors.white,
),
Icon(
Icons.home,
size: 25,
color: Colors.white,
),
Icon(
Icons.home,
size: 25,
color: Colors.white,
),
Icon(
Icons.home,
size: 25,
color: Colors.white,
),
],
color: Color.fromRGBO(241, 201, 57, 1.0),
buttonBackgroundColor: Colors.black,
backgroundColor: Colors.white,
animationCurve: Curves.easeInOut,
animationDuration: Duration(milliseconds: 600),
onTap: (index) {
setState(() {
_currentIndex = index;
});
}),
);
}
}
上面是homescreen.dart文件代码。
class Authentication with ChangeNotifier {
final FirebaseAuth firebaseAuth = FirebaseAuth.instance;
final GoogleSignIn googleSignIn = GoogleSignIn();
late String userUid;
String get getUserUid => userUid;
Future logIntoAccount(String email, String password) async {
UserCredential userCredential = await firebaseAuth
.signInWithEmailAndPassword(email: email, password: password);
String userUid;
User? user = userCredential.user;
userUid = user!.uid;
print(userUid);
notifyListeners();
}
Future createAccount(String email, String password) async {
UserCredential userCredential = await firebaseAuth
.createUserWithEmailAndPassword(email: email, password: password);
User? user = userCredential.user;
userUid = user!.uid;
print('Created Account Uid => $userUid');
notifyListeners();
}
Future logoutViaEmail() {
return firebaseAuth.signOut();
}
Future signInWithGoogle() async {
final GoogleSignInAccount? googleSignInAccount =
await googleSignIn.signIn();
final GoogleSignInAuthentication googleSignInAuthentication =
await googleSignInAccount!.authentication;
final AuthCredential authCredential = GoogleAuthProvider.credential(
accessToken: googleSignInAuthentication.accessToken,
idToken: googleSignInAuthentication.idToken);
final UserCredential userCredential =
await firebaseAuth.signInWithCredential(authCredential);
final User? user = userCredential.user;
assert(user!.uid != null);
userUid = user!.uid;
print('Google User Uid => $userUid');
notifyListeners();
}
Future signOutWithGoogle() async {
return googleSignIn.signOut();
}
}
上面是 Authentification.dart 文件。
class FirebaseOperations with ChangeNotifier {
late UploadTask imageUploadTask;
late String initUserEmail;
late String initUserImage;
late String initUserName;
String get getInitUserImage => initUserImage;
String get getInitUserName => initUserName;
String get getInitUserEmail => initUserEmail;
Future uploadUserAvatar(BuildContext context) async {
Reference imageReference = FirebaseStorage.instance.ref().child(
'userProfileAvatar/${Provider.of<LandingUtils>(context, listen:
false).getUserAvatar.path}/${TimeOfDay.now()}');
imageUploadTask = imageReference.putFile(
Provider.of<LandingUtils>(context, listen: false).getUserAvatar);
await imageUploadTask.whenComplete(() {
print('Image uploaded!');
});
imageReference.getDownloadURL().then((url) {
Provider.of<LandingUtils>(context, listen: false).userAvatarUrl =
url.toString();
print(
'the user profile avatar url => ${Provider.of<LandingUtils>(context, listen:
false).userAvatarUrl}');
notifyListeners();
});
}
Future createUserCollection(BuildContext context, dynamic data) async {
return FirebaseFirestore.instance
.collection('users')
.doc(Provider.of<Authentication>(context, listen: false).getUserUid)
.set(data);
}
Future initUserData(BuildContext context) async {
return FirebaseFirestore.instance
.collection('users')
.doc(Provider.of<Authentication>(context, listen: false).getUserUid)
.get()
.then((doc) {
print('Fetching user data');
initUserName = doc.data()!['username'];
initUserEmail = doc.data()!['useremail'];
initUserImage = doc.data()!['userimage'];
print(initUserName);
print(initUserEmail);
print(initUserImage);
notifyListeners();
});
}
Future uploadPostData(String postId, dynamic data) async {
return FirebaseFirestore.instance.collection('posts').doc(postId).set(data);
}
}
上面是 firebaseoperations.dart 文件。 在这里,一旦它在控制台中打印“获取用户数据”,就会显示“未处理的异常:空值检查运算符用于空值”错误。 同样,一旦图像上传,而不是打印图像的 url,而是打印 '*************'。 并且'未处理的异常:LateInitializationError:字段'initUserName'尚未初始化。也被打印出来了。
如果有人指出我的错误并给我解决方案,它将对我更有帮助。
Unhandled Exception: LateInitializationError: Field 'initUserName' has not been
initialized.
.
.
.
I/flutter (18214): Post image uploaded to storage
I/flutter (18214): Image uploaded
I/flutter (18214):
*************************************************************************************
*************************************************************************************
*********************************************
.
.
.
E/flutter (18214): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception:
LateInitializationError: Field 'initUserName' has not been initialized.
这就是错误的样子。
class ProfileHelpers with ChangeNotifier {
ConstantColors constantColors = ConstantColors();
Widget headerProfile(
BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
print(snapshot.data);
return SizedBox(
height: MediaQuery.of(context).size.height * 0.26,
width: MediaQuery.of(context).size.width,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
height: 150.0,
width: 170.0,
child: Column(
children: [
GestureDetector(
onTap: () {},
child: CircleAvatar(
backgroundColor: constantColors.transparent,
radius: 38.0,
backgroundImage: NetworkImage(
'${Provider.of<FirebaseOperations>
(context).getInitUserImage}'),
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Text(
'Vijay',
//snapshot.data?['username'],
//snapshot.data!.data()['username'],
style: TextStyle(
color: constantColors.whiteColor,
fontWeight: FontWeight.bold,
fontSize: 20.0),
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(EvaIcons.email,
color: constantColors.greenColor, size: 16),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Text(
'username@gmail.com',
// snapshot.data!.get('useremail'),
style: TextStyle(
color: constantColors.whiteColor,
fontWeight: FontWeight.bold,
fontSize: 12.0),
),
),
],
),
)
],
),
),
以上是个人资料页面代码。
enter code here
class FeedHelpers with ChangeNotifier {
ConstantColors constantColors = ConstantColors();
Widget appBar(BuildContext context) {
return AppBar(
backgroundColor: constantColors.darkColor.withOpacity(0.6),
centerTitle: true,
actions: [
IconButton(
icon: Icon(Icons.camera_enhance_rounded,
color: constantColors.greenColor),
onPressed: () {
Provider.of<UploadPost>(context, listen: false)
.selectPostImageType(context);
})
],
title: RichText(
text: TextSpan(
text: 'Social ',
style: TextStyle(
color: constantColors.whiteColor,
fontWeight: FontWeight.bold,
fontSize: 20.0,
),
children: <TextSpan>[
TextSpan(
text: 'Feed',
style: TextStyle(
color: constantColors.blueColor,
fontWeight: FontWeight.bold,
fontSize: 20.0,
))
]),
),
);
}
Widget feedBody(BuildContext context) {
return SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Container(
child: StreamBuilder<QuerySnapshot<Map<String, dynamic>>>(
stream:
FirebaseFirestore.instance.collection('posts').snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>>
snapshot) {
if (snapshot.connectionState == ConnectionState.waiting)
{
return Center(
child: SizedBox(
height: 500.0,
width: 400.0,
child:
Lottie.asset('assets/animations/loading.json'),
),
);
} else {
return loadPosts(context, snapshot);
}
},
),
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: constantColors.darkColor.withOpacity(0.6),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(18.0),
topRight: Radius.circular(18.0))),
),
),
);
}
Widget loadPosts(
BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
return ListView(
children: snapshot.data!.docs.map((DocumentSnapshot
documentSnapshot) {
Map<String, dynamic> data =
documentSnapshot.data()! as Map<String, dynamic>;
return Container(
height: MediaQuery.of(context).size.height * 0.62,
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(top: 8.0, left: 8.0),
child: Row(
children: [
GestureDetector(
child: CircleAvatar(
backgroundColor: constantColors.blueGreyColor,
radius: 20.0,
backgroundImage: NetworkImage(
'${Provider.of<UploadPost>
(context).getUploadPostImage}'),
// NetworkImage(documentSnapshot['userimage']),
),
),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Container(
width: MediaQuery.of(context).size.width * 0.6,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
child: RichText(
text: TextSpan(
text: data['username'],
style: TextStyle(
color: constantColors.blueColor,
fontSize: 14.0,
fontWeight: FontWeight.bold),
children: <TextSpan>[
TextSpan(
text: ' , 12 hours ago',
style: TextStyle(
color:
constantColors.lightColor
.withOpacity(0.8)))
]),
)),
Container(
child: Text(
data['username'],
style: TextStyle(
color: constantColors.greenColor,
fontWeight: FontWeight.bold,
fontSize: 16.0,
),
),
),
],
),
),
)
],
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Container(
height: MediaQuery.of(context).size.height * 0.46,
width: MediaQuery.of(context).size.width,
child: FittedBox(
// child: Image.network(downloadURL.toString()),
child: Image.network(data['postimage'], scale:
2))),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Padding(
padding: const EdgeInsets.only(left: 20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
width: 80.0,
child: Row(
children: [
GestureDetector(
child: Icon(
FontAwesomeIcons.heart,
color: constantColors.redColor,
size: 22.0,
),
),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Text(
'0',
style: TextStyle(
color: constantColors.whiteColor,
fontWeight: FontWeight.bold,
fontSize: 18.0),
),
)
],
),
),
上面是 feed_helper 文件。
class UploadPost with ChangeNotifier {
TextEditingController captionController = TextEditingController();
ConstantColors constantColors = ConstantColors();
late File uploadPost;
late File uploadPostImage;
File get getUploadPostImage => uploadPostImage;
late String uploadPostImageUrl;
String get getUploadPostImageUrl => uploadPostImageUrl;
final picker = ImagePicker();
late UploadTask imagePostUploadTask;
Future pickUploadPostImage(BuildContext context, ImageSource
source) async {
final uploadPostImageVal = await picker.pickImage(source: source);
uploadPostImageVal == null
? print('Select Image')
: uploadPostImage = File(uploadPostImageVal.path);
print(uploadPostImageVal!.path);
uploadPostImage != null
? showPostImage(context)
: print('Image upload error');
notifyListeners();
}
Future uploadPostImageToFirebase() async {
Reference imageReference = FirebaseStorage.instance
.ref()
.child('posts/${uploadPostImage!.path}/${TimeOfDay.now()}');
imagePostUploadTask = imageReference.putFile(uploadPostImage!);
await imagePostUploadTask.whenComplete(() {
print('Post image uploaded to storage');
});
imageReference.getDownloadURL().then((imageUrl) {
uploadPostImageUrl = imageUrl;
print(uploadPostImageUrl);
});
notifyListeners();
}
上面的文件是uploadpost.dart文件
【问题讨论】:
标签: firebase flutter dart firebase-authentication