Related
here is the error message from the console
user.dart
import 'package:cloud_firestore/cloud_firestore.dart';
class User {
final String email;
final String uid;
final String photoUrl;
final String username;
final String bio;
final List<String> followers;
final List<String> following;
const User({
required this.email,
required this.uid,
required this.photoUrl,
required this.username,
required this.bio,
required this.followers,
required this.following,
});
static User fromSnap(DocumentSnapshot snap) {
var snapshot = snap.data() as Map<String, dynamic>;
return User(
username: snapshot["username"],
uid: snapshot["uid"],
email: snapshot["email"],
photoUrl: snapshot["photoUrl"],
bio: snapshot["bio"],
followers: snapshot["followers"],
following: snapshot["following"],
);
}
Map<String, dynamic> toJson() => {
"username": username,
"uid": uid,
"email": email,
"photoUrl": photoUrl,
"bio": bio,
"followers": followers,
"following": following,
};
}
user_provider
import 'package:flutter/material.dart';
import 'package:social_network/models/user.dart';
import 'package:social_network/resources/auth_method.dart';
class UserProvider with ChangeNotifier {
User? _user;
final AuthMethods _authMethods = AuthMethods();
User get getUser => _user!;
Future<void> refreshUser() async {
User? user = await _authMethods.getUserDetails();
_user = user;
notifyListeners();
}
}
add_post_screen
import 'dart:typed_data';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:provider/provider.dart';
import 'package:social_network/providers/user_provider.dart';
import 'package:social_network/resources/firestore_methods.dart';
import 'package:social_network/utils/colors.dart';
import 'package:social_network/utils/utils.dart';
class AddPostScreen extends StatefulWidget {
const AddPostScreen({Key? key}) : super(key: key);
#override
_AddPostScreenState createState() => _AddPostScreenState();
}
class _AddPostScreenState extends State<AddPostScreen> {
Uint8List? _file;
bool _isLoading = false;
final TextEditingController _descriptionController = TextEditingController();
_selectImage(BuildContext parentContext) async {
return showDialog(
context: parentContext,
builder: (BuildContext context) {
return SimpleDialog(
title: const Text('Create a post'),
children: <Widget>[
SimpleDialogOption(
padding: const EdgeInsets.all(20),
child: const Text('Take a photo'),
onPressed: () async {
Navigator.of(context).pop();
Uint8List file = await pickImage(ImageSource.camera);
setState(() {
_file = file;
});
},
),
SimpleDialogOption(
padding: const EdgeInsets.all(20),
child: const Text('Choose from gallery'),
onPressed: () async {
Navigator.of(context).pop();
Uint8List file = await pickImage(ImageSource.gallery);
setState(() {
_file = file;
});
},
),
SimpleDialogOption(
padding: const EdgeInsets.all(20),
child: const Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
});
}
void postImage(
String uid,
String username,
String profileImage,
) async {
setState(() {
_isLoading = true;
});
try {
String res = await FirestoreMethods().uploadPost(
_descriptionController.text, _file!, uid, username, profileImage);
if (res == "Succes") {
setState(() {
_isLoading = false;
});
showSnackBar('Posted!', context);
clearImage();
} else {
showSnackBar(res, context);
}
} catch (e) {
setState(() {
_isLoading = false;
});
showSnackBar(e.toString(), context);
}
}
void clearImage() {
setState(() {
_file = null;
});
}
#override
void dispose() {
super.dispose();
_descriptionController.dispose();
}
#override
Widget build(BuildContext context) {
final UserProvider userProvider = Provider.of<UserProvider>(context);
return _file == null
? Center(
child: IconButton(
icon: const Icon(Icons.upload),
onPressed: () => _selectImage(context),
),
)
: Scaffold(
appBar: AppBar(
backgroundColor: mobileBackgroundColor,
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: clearImage,
),
title: const Text('Post to'),
centerTitle: false,
actions: <Widget>[
TextButton(
onPressed: () => postImage(
userProvider.getUser.uid,
userProvider.getUser.username,
userProvider.getUser.photoUrl,
),
child: const Text(
'Post',
style: TextStyle(
color: Colors.redAccent,
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
),
],
),
body: Column(
children: [
_isLoading
? const LinearProgressIndicator()
: const Padding(
padding: EdgeInsets.only(top: 0),
),
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CircleAvatar(
backgroundImage: NetworkImage(
'https://images.unsplash.com/photo-1522441815192-d9f04eb0615c?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=654&q=80',
// userProvider.getUser.photoUrl,
),
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.4,
child: TextField(
controller: _descriptionController,
decoration: const InputDecoration(
hintText: 'Write a caption...',
border: InputBorder.none,
),
maxLines: 8,
),
),
SizedBox(
height: 45,
width: 45,
child: AspectRatio(
aspectRatio: 487 / 451,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: MemoryImage(_file!),
fit: BoxFit.fill,
alignment: FractionalOffset.topCenter,
),
),
),
),
),
const Divider(),
],
)
],
));
}
}
auth_methods.dart
import 'dart:typed_data';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:social_network/models/user.dart' as model;
import 'package:social_network/resources/storage_methods.dart';
class AuthMethods {
final FirebaseAuth _auth = FirebaseAuth.instance;
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
Future<model.User?> getUserDetails() async {
User currentUser = _auth.currentUser!;
DocumentSnapshot documentSnapshot =
await _firestore.collection('user').doc(currentUser.uid).get();
return model.User.fromSnap(documentSnapshot);
}
//sign up the user
Future<String> signUpUser({
required String email,
required String password,
required String username,
required String bio,
required Uint8List? file,
}) async {
String res = "Some error occurred";
try {
if (email.isNotEmpty ||
password.isNotEmpty ||
username.isNotEmpty ||
bio.isNotEmpty ||
file != null) {
//register the user
UserCredential cred = await _auth.createUserWithEmailAndPassword(
email: email, password: password);
String photoUrl = await StorageMethods()
.uploadImageToStorage('profilePictures', file!, false);
//adding user to our database
model.User _user = model.User(
bio: bio,
username: username,
uid: cred.user!.uid,
email: email,
photoUrl: photoUrl,
following: [],
followers: [],
);
await _firestore.collection("users").doc(cred.user!.uid).set(
_user.toJson(),
);
res = "Succes";
} else {
res = "Please enter all the fields";
}
} catch (err) {
res = err.toString();
}
return res;
}
// logging the user
Future<String> loginUser(
{required String email, required String password}) async {
String res = "Some error occured";
try {
if (email.isNotEmpty || password.isNotEmpty) {
await _auth.signInWithEmailAndPassword(
email: email, password: password);
res = "Succes";
} else {
res = "Please enter all the fields required";
}
} catch (err) {
res = err.toString();
}
return res;
}
}
Hello. I'll try to make a post button and when I try to upload a photo and press the post button I receive this error.
Do you have any solution for this error? Thanks a lot!
Error message:
Restarted application in 474ms.
[VERBOSE-2:ui_dart_state.cc(198)] Unhandled Exception: type 'Null' is not a subtype of type 'Map<String, dynamic>' in type cast
════════ Exception caught by gesture ═══════════════════════════════════════════
Null check operator used on a null value
════════════════════════════════════════════════════════════════════════════════
[VERBOSE-2:profiler_metrics_ios.mm(203)] Error retrieving thread information: (os/kern) object terminated
I believe that your issue in
onPressed: () => postImage(
userProvider.getUser.uid,
userProvider.getUser.username,
userProvider.getUser.photoUrl,
),
Make sure that the user is not null before calling the method,
It would be more helpful to post more code _authMethods.getUserDetails(); what’s inside this method?
UPDATE:
Future<model.User?> getUserDetails() async {
User currentUser = _auth.currentUser!;
DocumentSnapshot documentSnapshot =
await _firestore.collection('user').doc(currentUser.uid).get();
//add the following lines
print('documentSnapshot: $documentSnapshot');
if(documentSnapshot == null) return null;
return model.User.fromSnap(documentSnapshot);
}
The logic in the program I wrote is that it is like Twitter. There will be photo sharing and text sharing. However, there is an error in my codes and when I do not share photos, I get the error 'Null check-operator used on null value'. How can I change this?
When I do not share photos, I get the error below.
These are my codes. I would appreciate it if you could tell me the changes I need to make.
add_post_screenn
class AddPostScreen extends StatefulWidget {
const AddPostScreen({Key? key}) : super(key: key);
#override
State<AddPostScreen> createState() => _AddPostScreenState();
}
class _AddPostScreenState extends State<AddPostScreen> {
Uint8List? _file;
final TextEditingController _descriptionController = TextEditingController();
bool _isLoading = false;
void postImage(
String uid,
String username,
String profImage,
) async {
setState(() {
_isLoading = true;
});
try {
String res = await FirestoreMethods().uploadPost(
_descriptionController.text, _file!, uid, username, profImage);
if (res == 'succes') {
setState(() {
_isLoading = false;
});
showSnackBar('Posted!', context);
clearImage();
} else {
showSnackBar(res, context);
}
} catch (e) {
showSnackBar(e.toString(), context);
}
}
_selectImage(BuildContext context) async {
return showDialog(
context: context,
builder: (context) {
return SimpleDialog(
title: const Text('Create a Post'),
children: [
SimpleDialogOption(
padding: const EdgeInsets.all(20),
child: const Text('Take a photo'),
onPressed: () async {
Navigator.of(context).pop();
Uint8List file = await pickImage(
ImageSource.camera,
);
setState(() {
_file = file;
});
},
),
SimpleDialogOption(
padding: const EdgeInsets.all(20),
child: const Text('Chose from gallery'),
onPressed: () async {
Navigator.of(context).pop();
Uint8List file = await pickImage(
ImageSource.gallery,
);
setState(() {
_file = file;
});
},
),
SimpleDialogOption(
padding: const EdgeInsets.all(20),
child: const Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
}),
],
);
});
}
void clearImage() {
_file = null;
}
#override
void dispose() {
super.dispose();
_descriptionController.dispose();
}
#override
Widget build(BuildContext context) {
final User user = Provider.of<UserProvider>(context).getUser;
//yorum satırı olacak
return _file == null
? Center(
child: IconButton(
icon: const Icon(Icons.upload),
onPressed: () => _selectImage(context),
),
)
// //buraya kadar
: Scaffold(
appBar: AppBar(
backgroundColor: mobileBackgroundColor,
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: clearImage,
),
title: const Text('Paylaşım'),
centerTitle: false,
actions: [
TextButton(
onPressed: () => postImage(
user.uid,
user.username,
user.photoUrl,
),
child: const Text(
'Paylaş',
style: TextStyle(
color: Colors.blueAccent,
fontWeight: FontWeight.bold,
fontSize: 16,
),
))
],
),
body: Column(
children: [
_isLoading
? const LinearProgressIndicator()
: const Padding(
padding: EdgeInsets.only(
top: 0,
),
),
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CircleAvatar(
backgroundImage: NetworkImage(user.photoUrl),
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.45,
child: TextField(
controller: _descriptionController,
decoration: const InputDecoration(
hintText: 'Hayallerini Yaz!',
border: InputBorder.none,
),
maxLines: 8,
),
),
SizedBox(
height: 45,
width: 45,
child: AspectRatio(
aspectRatio: 487 / 451,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: MemoryImage(_file!),
fit: BoxFit.fill,
alignment: FractionalOffset.topCenter,
)),
),
),
),
const Divider(),
],
),
],
),
);
}
}
firestore_methods
class FirestoreMethods {
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
//upload post
Future<String> uploadPost(
String description,
Uint8List file,
String uid,
String username,
String profImage,
) async {
String res = 'Some error occurred';
try {
String photoUrl =
await StorageMethods().uploadImageToStorage('posts', file, true);
String postId = const Uuid().v1();
Post post = Post(
description: description,
uid: uid,
username: username,
postId: postId,
datePublished: DateTime.now(),
postUrl: photoUrl,
porfImage: profImage,
likes: [],
);
_firestore.collection('posts').doc(postId).set(
post.toJson(),
);
res = 'succes';
} catch (err) {
res = err.toString();
}
return res;
}
Future<void> LikePost(String postId, String uid, List likes) async {
try {
if (likes.contains(uid)) {
await _firestore.collection('posts').doc(postId).update({
'likes': FieldValue.arrayRemove([uid]),
});
} else {
await _firestore.collection('posts').doc(postId).update({
'likes': FieldValue.arrayUnion([uid]),
});
}
} catch (e) {
print(
e.toString(),
);
}
}
Future<void> postComment(String postId, String text, String uid, String name,
String profilePic) async {
try {
if (text.isNotEmpty) {
String commentId = const Uuid().v1();
await _firestore
.collection('posts')
.doc(postId)
.collection('comments')
.doc(commentId)
.set({
'profilePic': profilePic,
'name': name,
'uid': uid,
'text': text,
'commentId': commentId,
'datePublished': DateTime.now(),
});
} else {
print('Text is empty');
}
} catch (e) {
print(
e.toString(),
);
}
}
storage.methods
class StorageMethods {
final FirebaseAuth _auth = FirebaseAuth.instance;
final FirebaseStorage _storage = FirebaseStorage.instance;
// firebase deposuna resim ekleme firebase deposuna resim ekleme
Future<String> uploadImageToStorage(
String childName, Uint8List file, bool isPost) async {
// firebase depolama alanımıza konum oluşturma
Reference ref =
_storage.ref().child(childName).child(_auth.currentUser!.uid);
if (isPost) {
String id = const Uuid().v1();
ref = ref.child(id);
}
// putting in uint8list format -> Upload task like a future but not future
UploadTask uploadTask = ref.putData(file);
TaskSnapshot snap = await uploadTask;
String downloadUrl = await snap.ref.getDownloadURL();
return downloadUrl;
}
}
The error cause comes from the _file!. When posting only text there is going to be no _file as it's going to be null.
To fix this change the references from _file! to just _file and the FirestoreMethods.uploadPost should be the following:
FirestoreMethods.uploadPost - Change file to be nullable and check for null.
Future<String> uploadPost(
String description,
Uint8List? file, // <- Here
String uid,
String username,
String profImage,
) async {
String res = 'Some error occurred';
try {
String photoUrl = file != null // <- Here
? await StorageMethods().uploadImageToStorage('posts', file, true)
: '';
String postId = const Uuid().v1();
Post post = Post(
description: description,
uid: uid,
username: username,
postId: postId,
datePublished: DateTime.now(),
postUrl: photoUrl,
porfImage: profImage,
likes: [],
);
_firestore.collection('posts').doc(postId).set(
post.toJson(),
);
res = 'succes';
} catch (err) {
res = err.toString();
}
return res;
}
_AddPostScreenState.postImage - Change _file! to just _file
void postImage(
String uid,
String username,
String profImage,
) async {
setState(() {
_isLoading = true;
});
try {
String res = await FirestoreMethods().uploadPost(
_descriptionController.text, _file, uid, username, profImage);
if (res == 'succes') {
setState(() {
_isLoading = false;
});
showSnackBar('Posted!', context);
clearImage();
} else {
showSnackBar(res, context);
}
} catch (e) {
showSnackBar(e.toString(), context);
}
}
I think you are getting error in this line
Reference ref =
_storage.ref().child(childName).child(_auth.currentUser!.uid);
Here the current user maybe null. To fix this error for now you can use
Reference ref =
_storage.ref().child(childName).child(_auth.currentUser?.uid);
//Note instead of using ! I have used ? which means currentUser can be null. ! means you are marking that its not null and value is unknown
but please note that you are receiving _auth.currentUser as null. Please check those codes
I'm a new Flutter user, here I'm having a problem, I'm confused about how to make a search that reads from JSON, here I've created a search menu but I don't understand how to connect to the database. Can you help me to modify my source code so I can do a search. Hopefully good friends can help me make a search function. Thank you friend
datanasabah.dart
GlobalKey<ScaffoldState> _scaffoldState = GlobalKey<ScaffoldState>();
class DataNasabah extends StatefulWidget {
DataNasabah({Key key}) : super(key: key);
final String title = "Data Nasabah";
#override
_DataNasabahState createState() => _DataNasabahState();
}
class _DataNasabahState extends State<DataNasabah> {
ApiService apiService;
ListNasabah _listNasabah;
bool _isLoading = true;
List<Nasabah> data;
final _textHeadStyle =
TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold);
void fetchData() async {
final res = await apiService.getNasabah();
data = res;
setState(() {
_isLoading = false;
});
}
#override
void initState() {
super.initState();
apiService = ApiService();
_listNasabah = new ListNasabah(apiService: apiService);
fetchData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldState,
appBar: AppBar(
title: Text(
'Data Nasabah',
style: TextStyle(color: Colors.white),
),
actions: <Widget>[
MaterialButton(
elevation: 5,
child: Text("CARI", style: _textHeadStyle),
onPressed: () async {
var value = await showTopModalSheet<String>(
context: context, child: DumyModal());
},
),
],
),
body: _listNasabah.createViewList(),
);
}
}
class DumyModal extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
height: MediaQuery.of(context).size.height * .2,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
TextField(
decoration: InputDecoration(
labelText: "NIK Nasabah", //babel text
hintText: "Masukkan NIK Nasabah", //hint text
prefixIcon: Icon(Icons.people), //prefix iocn
hintStyle: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, ), //hint text style
labelStyle: TextStyle(fontSize: 17, color: Colors.black), //label style
)
),
MaterialButton(
color: Colors.orange,
child: const Text("Cari", style: TextStyle(color: Colors.white),),
onPressed: () {
FocusScope.of(context).requestFocus(FocusNode());
},
)
],
),
);
}
}
nasabah_service.dart
class ApiService {
final String baseUrl = '192.168.100.207:8080';
Client client = Client();
Future<List<Nasabah>> getNasabah() async {
final response = await client.get('http://$baseUrl/api/mstdebitur');
print(response.body);
if (response.statusCode == 200) {
final nasabah = (json.decode(response.body) as List)
.map((e) => Nasabah.fromMap(e))
.toList();
return nasabah;
} else {
throw Exception('Failed to load post');
}
}
Future<bool> createNasabah(Nasabah data) async {
String url = new Uri.http("$baseUrl", "/api/mstdebitur/").toString();
final response = await client.post(url,
headers: {"Content-Type": "application/json"},
body: nasabahToJson(data));
if (response.statusCode == 201) {
return true;
} else {
return false;
}
}
Future<bool> updateNasabah(Nasabah data) async {
String url =
new Uri.http("$baseUrl", "/api/mstdebitur/${data.id}").toString();
final response = await client.put(url,
headers: {"Content-Type": "application/json"},
body: nasabahToJson(data));
if (response.statusCode == 200) {
return true;
} else {
return false;
}
}
Future<bool> deleteNasabah(int id) async {
String url = new Uri.http("$baseUrl", "/api/mstdebitur/$id").toString();
final response = await client.delete(url);
if (response.statusCode == 200) {
return true;
} else {
return false;
}
}
}
I am tring to pas data to user profile screen from firebase
i have got error Unhandled Exception: 'package:cloud_firestore/src/collection_reference.dart': Failed assertion: line 116 pos 14: 'path.isNotEmpty': a document path must be a non-empty string
what do i need fix?
user prfile controller
lass ProfileController extends GetxController {
final Rx<Map<String, dynamic>> _user = Rx<Map<String, dynamic>>({});
Map<String, dynamic> get user => _user.value;
Rx<String> _uid = ''.obs;
updateUserID(String uid) {
_uid.value = uid;
getUserData();
}
void getUserData() async {
print("HELLO");
List<String> thumbnails = [];
// var myVideos = await firestore
// .collection('videos')
// .where('uid', isEqualTo: "9GFyxV41rkd0Iu0oy1tctobVNk92")
// .get();
//
// for (int i = 0; i < myVideos.docs.length; i++) {
// thumbnails.add((myVideos.docs[i].data() as dynamic)['thumbnail']);
// }
DocumentSnapshot userDoc =
await firestore.collection('users').doc(_uid.value).get();
final userData = userDoc.data()! as dynamic;
print(userData);
String name = userData['name'];
String profilePhoto = userData['profilePhoto'];
int likes = 0;
int followers = 0;
int following = 0;
bool isFollowing = false;
// for (var item in myVideos.docs) {
// likes += (item.data()['likes'] as List).length;
// }
// var followerDoc = await firestore
// .collection('users')
// .doc(_uid.value)
// .collection('followers')
// .get();
// var followingDoc = await firestore
// .collection('users')
// .doc(_uid.value)
// .collection('following')
// .get();
// followers = followerDoc.docs.length;
// following = followingDoc.docs.length;
// firestore
// .collection('users')
// .doc(_uid.value)
// .collection('followers')
// .doc(authController.user.uid)
// .get()
// .then(
// (value) {
// if (value.exists) {
// isFollowing = true;
// } else {
// isFollowing = false;
// }
// },
// );
_user.value = {
'followers': followers.toString(),
'following': following.toString(),
'isFollowing': isFollowing,
'likes': likes.toString(),
'profilePhoto': profilePhoto,
'name': name,
'thumbnails': thumbnails,
};
update();
}
followUser() async {
var doc = await firestore
.collection('users')
.doc(_uid.value)
.collection('followers')
.doc(authController.user.uid)
.get();
if (!doc.exists) {
await firestore
.collection('users')
.doc(_uid.value)
.collection('followers')
.doc(authController.user.uid)
.set({});
await firestore
.collection('users')
.doc(authController.user.uid)
.collection('following')
.doc(_uid.value)
.set({});
_user.value
.update('followers', (value) => (int.parse(value) + 1).toString());
} else {
await firestore
.collection('users')
.doc(_uid.value)
.collection('followers')
.doc(authController.user.uid)
.delete();
await firestore
.collection('users')
.doc(authController.user.uid)
.collection('following')
.doc(_uid.value)
.delete();
_user.value
.update('followers', (value) => (int.parse(value) - 1).toString());
}
_user.value.update('isFollowing', (value) => !value);
update();
}
}
auth Controller
class AuthController extends GetxController {
static AuthController instance = Get.find(); //TODO 2
var displayName = '';
var displayPhoto = '';
String myId = '';
late Rx<User?> _user; //TODO 1
User get user => _user.value!; //TODO 3
Rx<File?>? pickedImageVal;
File? get profilePhoto => pickedImageVal!.value;
FirebaseAuth auth = FirebaseAuth.instance;
User? get userProfile => auth.currentUser;
var isSignedIn = false.obs;
var _googleSignIn = GoogleSignIn();
var googleAccount = Rx<GoogleSignInAccount?>(null);
var firebaseStorage = FirebaseStorage.instance;
var firestore = FirebaseFirestore.instance;
// var authController = AuthController.instance;
#override
void onReady() {
super.onReady();
_user = Rx<User?>(firebaseAuth.currentUser);
_user.bindStream(firebaseAuth.authStateChanges());
ever(_user, _setInitialScreen);
}
_setInitialScreen(User? user) {
if (user == null) {
Get.offAll(OnboardingPage());
} else {
Get.offAll(const Home());
}
}
#override
void onInit() {
displayName = userProfile != null ? userProfile!.displayName! : '';
super.onInit();
}
void pickImage() async {
final pickedImage =
await ImagePicker().pickImage(source: ImageSource.gallery);
if (pickedImage != null) {
Get.snackbar(
'プロファイル写真', 'You have successfully selected your profile picture!');
}
pickedImageVal = Rx<File?>(File(pickedImage!.path));
}
Future<String> _uploadToStorage(File image) async {
Reference ref =
firebaseStorage.ref().child('profilePics').child(auth.currentUser!.uid);
UploadTask uploadTask = ref.putFile(image);
TaskSnapshot snap = await uploadTask;
String downloadUrl = await snap.ref.getDownloadURL();
return downloadUrl;
}
void signUp(String name, String email, String password, File? image) async {
try {
await auth
.createUserWithEmailAndPassword(email: email, password: password)
.then((value) {
displayName = name;
auth.currentUser!.updateDisplayName(name);
});
isSignedIn = true.obs;
String downloadUrl = await _uploadToStorage(profilePhoto!);
model.UserM user = model.UserM(
name: name,
email: email,
uid: auth.currentUser!.uid,
profilePhoto: downloadUrl,
);
await firestore
.collection('users')
.doc(auth.currentUser!.uid)
.set(user.toJson());
update();
Get.offAll(() => Root());
} on FirebaseAuthException catch (e) {
String title = e.code.replaceAll(RegExp('-'), ' ').capitalize!;
String message = '';
if (e.code == 'weak-password') {
message = 'The password provided is too weak.';
} else if (e.code == 'email-already-in-use') {
message = ('The account already exists for that email.');
} else {
message = e.message.toString();
}
Get.snackbar(title, message,
snackPosition: SnackPosition.BOTTOM,
backgroundColor: kPrimaryColor,
colorText: Colors.white);
} catch (e) {
Get.snackbar('Error occured!', e.toString(),
snackPosition: SnackPosition.BOTTOM,
backgroundColor: kPrimaryColor,
colorText: Colors.white);
}
}
void signIn(String email, String password) async {
try {
await auth
.signInWithEmailAndPassword(email: email, password: password)
.then((value) => displayName = userProfile!.displayName!);
isSignedIn = true.obs;
myId = userProfile!.uid; //TODO 4
update();
Get.offAll(() => Root());
} on FirebaseAuthException catch (e) {
String title = e.code.replaceAll(RegExp('-'), ' ').capitalize!;
String message = '';
if (e.code == 'wrong-password') {
message = 'Invalid Password. Please try again!';
} else if (e.code == 'user-not-found') {
message =
('The account does not exists for $email. Create your account by signing up.');
} else {
message = e.message.toString();
}
Get.snackbar('ユーザー名が存在しません。', 'アカウントを作成してください。',
snackPosition: SnackPosition.BOTTOM,
backgroundColor: kPrimaryColor,
colorText: Colors.white);
} catch (e) {
//TODO; what is Get.snackbar.e.tostring(), means?
Get.snackbar(
'Error occured!',
e.toString(),
snackPosition: SnackPosition.BOTTOM,
backgroundColor: kPrimaryColor,
colorText: Colors.white,
);
}
}
void resetPassword(String email) async {
try {
await auth.sendPasswordResetEmail(email: email);
Get.back();
} on FirebaseAuthException catch (e) {
String title = e.code.replaceAll(RegExp('-'), ' ').capitalize!;
String message = '';
if (e.code == 'user-not-found') {
message =
('The account does not exists for $email. Create your account by signing up.');
} else {
message = e.message.toString();
}
Get.snackbar(title, message,
snackPosition: SnackPosition.BOTTOM,
backgroundColor: kPrimaryColor,
colorText: Colors.white);
} catch (e) {
Get.snackbar('Error occured!', e.toString(),
snackPosition: SnackPosition.BOTTOM,
backgroundColor: kPrimaryColor,
colorText: Colors.white);
}
}
void signInWithGoogle() async {
try {
googleAccount.value = await _googleSignIn.signIn();
print(googleAccount.value);
displayName = googleAccount.value!.displayName!;
displayPhoto = googleAccount.value!.photoUrl!;
isSignedIn.value = true;
update(); // <-- without this the isSignedin value is not updated.
} catch (e) {
Get.snackbar('Error occured!', e.toString(),
snackPosition: SnackPosition.BOTTOM,
backgroundColor: kPrimaryColor,
colorText: Colors.white);
}
}
void signout() async {
try {
await auth.signOut();
await _googleSignIn.signOut();
displayName = '';
isSignedIn.value = false;
update();
Get.offAll(() => Root());
} catch (e) {
Get.snackbar('Error occured!', e.toString(),
snackPosition: SnackPosition.BOTTOM,
backgroundColor: kPrimaryColor,
colorText: Colors.white);
}
}
}
//
// extension StringExtention on String{
// String capitalizedString(){
// return'${this[0].toUpperCase()}${this.substring(1)}';
// }
// }
user profile screen
class ProfileScreen extends StatefulWidget {
final String uid;
ProfileScreen({Key? key, required this.uid}) : super(key: key);
#override
State<ProfileScreen> createState() => _ProfileScreenState();
}
class _ProfileScreenState extends State<ProfileScreen> {
final ProfileController profileController = Get.put(ProfileController());
#override
void initState() {
super.initState();
profileController.updateUserID(widget.uid);
}
#override
Widget build(BuildContext context) {
return GetBuilder<ProfileController>(
init: ProfileController(),
builder: (controller) {
// if (controller.user.isEmpty) {
// return Center(
// child: CircularProgressIndicator(),
// );
// }
print(controller.user);
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.black12,
leading: Icon(Icons.person_add_alt_1_outlined),
actions: [
Icon(Icons.more_horiz),
],
title: Text(controller.user['name'].toString()),
),
body: SafeArea(
child: SingleChildScrollView(
child: Column(
children: [
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ClipOval(
child: CachedNetworkImage(
fit: BoxFit.cover,
imageUrl: controller.user['profilePhoto']
.toString(),
height: 100,
width: 100,
placeholder: (context, url) =>
CircularProgressIndicator(),
errorWidget: (context, url, error) =>
Icon(Icons.error)),
)
],
),
SizedBox(
height: 15,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
children: [
Text(controller.user['following'].toString()),
SizedBox(
height: 5,
),
Text('following'),
],
),
Container(
color: Colors.black54,
width: 1,
height: 15,
margin: EdgeInsets.symmetric(horizontal: 15),
),
Column(
children: [
Text(controller.user['followers'].toString()),
SizedBox(
height: 5,
),
Text('follower'),
],
),
Container(
color: Colors.black54,
width: 1,
height: 15,
margin: EdgeInsets.symmetric(horizontal: 15),
),
Column(
children: [
Text(controller.user['likes'].toString()),
SizedBox(
height: 5,
),
Text('likes'),
],
)
],
),
SizedBox(
height: 15,
),
Container(
width: 140,
height: 47,
decoration: BoxDecoration(
border: Border.all(
color: Colors.black12,
),
),
child: Center(
child: InkWell(
onTap: () {
// if (widget.uid == authController.user.uid) {
// authController.signOut();
// } else {
// controller.followUser();
},
// },
child: const Text(
"",
// widget.uid == authController.user.uid
// ? 'sign out'
// controller.user['isFollowing']
// ? 'unfollow'
// : 'follow',
),
),
),
),
Bonjour tout le monde,
I have this error message in my console, I searched for several days without finding the answer.
error message:
Unhandled Exception: NoSuchMethodError: The method '[]' was called on null. Tried calling:
Can you help me? here is my code:
final auth = FirebaseAuth.instance;
final googleSignIn = GoogleSignIn();
final ref = FirebaseFirestore.instance.collection('Users');
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
Users currentUserModel;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized(); // after upgrading flutter this is now necessary
await Firebase.initializeApp();
// enable timestamps in firebase
runApp(MyApp());
}
Future<Null> _ensureLoggedIn(BuildContext context) async {
GoogleSignInAccount user = googleSignIn.currentUser;
if (user == null) {
user = await googleSignIn.signInSilently();
}
if (user == null) {
await googleSignIn.signIn();
await tryCreateUserRecord(context);
}
if (await auth.currentUser == null) {
final GoogleSignInAccount googleUser = await googleSignIn.signIn();
final GoogleSignInAuthentication googleAuth = await googleUser
.authentication;
final AuthCredential credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
await auth.signInWithCredential(credential);
}
}
Future<Null> _silentLogin(BuildContext context) async {
GoogleSignInAccount user = googleSignIn.currentUser;
if (user == null) {
user = await googleSignIn.signInSilently();
await tryCreateUserRecord(context);
}
if (await auth.currentUser == null && user != null) {
final GoogleSignInAccount googleUser = await googleSignIn.signIn();
final GoogleSignInAuthentication googleAuth = await googleUser
.authentication;
final AuthCredential credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
await auth.signInWithCredential(credential);
}
}
Future<Null> _setUpNotifications() async {
if (Platform.isAndroid) {
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print('on message $message');
},
onResume: (Map<String, dynamic> message) async {
print('on resume $message');
},
onLaunch: (Map<String, dynamic> message) async {
print('on launch $message');
},
);
_firebaseMessaging.getToken().then((token) {
print("Firebase Messaging Token: " + token);
FirebaseFirestore.instance
.collection("Users")
.doc(currentUserModel.id)
.update({"androidNotificationToken": token});
});
}
}
Future<void> tryCreateUserRecord(BuildContext context) async {
GoogleSignInAccount user = googleSignIn.currentUser;
if (user == null) {
return null;
}
DocumentSnapshot userRecord = await ref.doc(user.id).get();
if (userRecord.data == null) {
// no user record exists, time to create
String userName = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Center(
child: Scaffold(
appBar: AppBar(
leading: Container(),
title: Text('Fill out missing data',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold)),
backgroundColor: Colors.white,
),
body: ListView(
children: <Widget>[
Container(
child: CreateAccount(),
),
],
)),
)),
);
if (userName != null || userName.length != 0) {
ref.doc(user.id).set({
"id": user.id,
"username": userName,
"photoUrl": user.photoUrl,
"email": user.email,
"displayName": user.displayName,
"bio": "",
"followers": {},
"following": {},
});
}
userRecord = await ref.doc(user.id).get();
}
currentUserModel = Users.fromDocument(userRecord);
return null;
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'MyApp',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or press Run > Flutter Hot Reload in IntelliJ). Notice that the
// counter didn't reset back to zero; the application is not restarted.
primarySwatch: Colors.blue,
buttonColor: Colors.pink,
primaryIconTheme: IconThemeData(color: Colors.black)),
home: HomePage(title: 'Myapp'),
);
}
}
class HomePage extends StatefulWidget {
HomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_HomePageState createState() => _HomePageState();
}
PageController pageController;
class _HomePageState extends State<HomePage> {
int _page = 0;
bool triedSilentLogin = false;
bool setupNotifications = false;
Scaffold buildLoginPage() {
return Scaffold(
body: Center(
child: Padding(
padding: const EdgeInsets.only(top: 240.0),
child: Column(
children: <Widget>[
Text(
'MyApp',
style: TextStyle(
fontSize: 60.0,
fontFamily: "Billabong",
color: Colors.black),
),
Padding(padding: const EdgeInsets.only(bottom: 100.0)),
GestureDetector(
onTap: login,
child: Image.asset(
"assets/images/google_signin_button.png",
width: 225.0,
),
)
],
),
),
),
);
}
#override
Widget build(BuildContext context) {
if (triedSilentLogin == false) {
silentLogin(context);
}
if (setupNotifications == false && currentUserModel != null) {
setUpNotifications();
}
return (googleSignIn.currentUser == null || currentUserModel == null)
? buildLoginPage()
: Scaffold(
body: PageView(
children: [
Container(
color: Colors.white,
child: Feed(),
),
Container(color: Colors.white, child: SearchPage()),
Container(
color: Colors.white,
child: Uploader(),
),
Container(
color: Colors.white, child: ActivityFeedPage()),
Container(
color: Colors.white,
child: ProfilePage(
userId: googleSignIn.currentUser.id,
)),
],
controller: pageController,
physics: NeverScrollableScrollPhysics(),
onPageChanged: onPageChanged,
),
bottomNavigationBar: CupertinoTabBar(
backgroundColor: Colors.white,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home,
color: (_page == 0) ? Colors.black : Colors.grey),
title: Container(height: 0.0),
backgroundColor: Colors.white),
BottomNavigationBarItem(
icon: Icon(Icons.search,
color: (_page == 1) ? Colors.black : Colors.grey),
title: Container(height: 0.0),
backgroundColor: Colors.white),
BottomNavigationBarItem(
icon: Icon(Icons.add_circle,
color: (_page == 2) ? Colors.black : Colors.grey),
title: Container(height: 0.0),
backgroundColor: Colors.white),
BottomNavigationBarItem(
icon: Icon(Icons.star,
color: (_page == 3) ? Colors.black : Colors.grey),
title: Container(height: 0.0),
backgroundColor: Colors.white),
BottomNavigationBarItem(
icon: Icon(Icons.person,
color: (_page == 4) ? Colors.black : Colors.grey),
title: Container(height: 0.0),
backgroundColor: Colors.white),
],
onTap: navigationTapped,
currentIndex: _page,
),
);
}
void login() async {
await _ensureLoggedIn(context);
setState(() {
triedSilentLogin = true;
});
}
void setUpNotifications() {
_setUpNotifications();
setState(() {
setupNotifications = true;
});
}
void silentLogin(BuildContext context) async {
await _silentLogin(context);
setState(() {
triedSilentLogin = true;
});
}
void navigationTapped(int page) {
//Animating Page
pageController.jumpToPage(page);
}
void onPageChanged(int page) {
setState(() {
this._page = page;
});
}
#override
void initState() {
super.initState();
pageController = PageController();
}
#override
void dispose() {
super.dispose();
pageController.dispose();
}
}
and my user.dart:
class Users {
final String email;
final String id;
final String photoUrl;
final String username;
final String displayName;
final String bio;
final Map followers;
final Map following;
const Users(
{this.username,
this.id,
this.photoUrl,
this.email,
this.displayName,
this.bio,
this.followers,
this.following});
factory Users.fromDocument(DocumentSnapshot doc) {
return Users(
id: doc.id,
username: doc.data()['username'],
email: doc.data()['email'],
photoUrl: doc.data()['photoUrl'],
displayName: doc.data()['displayName'],
bio: doc.data()['bio'],
followers: doc.data()['followers'],
following: doc.data()['following'],
);
}
}
I think the problem is with my factory in the user.dart file, but I'm not sure ... I'm still looking ... thanks for your help