when i try to access the user profile by clicking on the profile icon it cause me this error that don't let get to profile page and block whole the app
Profile page source code:
import 'package:cached_network_image/cached_network_image.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:yumor/models/progress.dart';
import 'package:yumor/models/user_model.dart';
class profile extends StatefulWidget {
const profile({Key? key,required this.userProfile}) : super(key: key);
final String? userProfile;
@override
State<profile> createState() => _profileState();
}
class _profileState extends State<profile> {
final userRef = FirebaseFirestore.instance.collection('users');
Future<UserModel?> getData() async {
final userRef = FirebaseFirestore.instance.collection('users');
final doc = await userRef.doc(widget.userProfile).get();
if (doc.exists) {
var data = doc.data();
} else {
return null;
}
final data = await FirebaseFirestore.instance
.collection('users')
.doc(userRef.id)
.get();
if (data.exists) {
UserModel user = UserModel.fromMap(data.data()!);
return user;
}
}
late final future = getData();
Widget buildprofileheader() {
return FutureBuilder<UserModel?>(future:future,
builder: ((context, snapshot) {
if(!snapshot.hasData){
UserModel user=UserModel.fromMap(userRef.parameters);
return Padding(padding:EdgeInsets.all(16.0),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.account_circle, size: 90,)
],
),
Container(
alignment: Alignment.center,
padding: EdgeInsets.all(12.0),
child: Text(
user.Username as String,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize:16.0,
),
),
),
],
),
);}
else{
return CircularProgress();}
}),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text(
"Profile",
),
),
body: ListView(children: <Widget>[
buildprofileheader(),
]));
}
}
User model(user firebase user creation):
import 'package:flutter/foundation.dart';
class UserModel {
String? uid;
String? Username;
String? email;
String? photoUrl;
UserModel(
{this.uid, this.email, this.Username, this.photoUrl});
// receving data from the server
factory UserModel.fromMap(map) {
return UserModel(
uid: map['userId'], // also this line was causing NoSuchMethodError <========
Username: map['Username'],
email: map['email'],
photoUrl: map['photoUrl'],
);
}
// /// sending data to firestore
Map<String, dynamic> toMap() {
return {
'userId': uid,
'Username': Username,
'email': email,
'photoUrl': photoUrl,
};
}
}
NoSuchMethodError (NoSuchMethodError: Class 'Type' has no instance method '[]'. Receiver: Map<dynamic, dynamic> Tried calling: ) called in this code
the error step by step :
here what happen when i click first there is the app
here after some seconds after i click on the profile icon this page appear
CodePudding user response:
Dont force with as prefix, Try with
Text( user.Username ?? "defaultValueOnNullCase",)
Or
show null on null case
Text( "${user.Username}",)
Or check null then show on UI.
if(user.Username!=null) Text(user.Username)
And your FutureBuilder condition will be
builder: ((context, snapshot) {
if(snapshot.hasData){ /// on has Data, remove not `!`
UserModel user=UserModel.fromMap(userRef.parameters);
return Padding(padding:EdgeInsets.all(16.0),
CodePudding user response:
This is related to null safety. You have to manually handle what happens to the UI when the value is null since Text
widget only accepts a String not null.
In UserModel
you have set the type of Username
as String?
which means it is a String but can also be null. So since you have mentioned the value can be null you have to handle the UI in that specific case.
...
Container(
alignment: Alignment.center,
padding: EdgeInsets.all(12.0),
child: Text(
user.Username ?? "Unknown", // show "Unknown" if null.
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize:16.0,
),
...
Learn more about Null Safety in dart.dev.