flutter firebase fire authentication - error since update - firebase

Since I have updated flutter and Android Studio, I am getting an error with a code which was working fine previously. I have done some research but have not find the right solution. Please, can you help me to solve this? Many thanks
if (snapshot.connectionState == ConnectionState.done) {
return StreamBuilder(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
User user = snapshot.data; // error A value of type 'Object?' can't be assigned to a variable of type 'User'.
if (user == null) {
return LoginPageTest();
``

You should have activated null safety, so User user is declared to not accept null, but snapshot.data can be null so is incompatible. You can declase user as nullable, adding a ?, like bellow:
User? user = snapshot.data;

You have to define StreamBuilder data type. By default it Object? (with null safety). Here is your updated code, try this
if (snapshot.connectionState == ConnectionState.done) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
User? user = snapshot.data;
if (user == null) {
return LoginPageTest();
``

Related

getting null error when using .where('uid', isEqualTo: uid) in firebase flutter

we are making home page like Instagram and I want to show only the user post for now.
the code was like this
StreamBuilder(
stream: FirebaseFirestore.instance.collection('posts').orderBy("datePublished", descending: true).snapshots(),
builder: (context,
AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
}
return PageView.builder(/*the rest of the code ...*/);
it worked but it shows all the post so I added this
.where('uid', isEqualTo: uid)
and it looks like this
inside Widget build
var uid = FirebaseAuth.instance.currentUser!.uid;
inside body like this
StreamBuilder(
stream: FirebaseFirestore.instance.collection('posts').where('uid', isEqualTo: uid).orderBy("datePublished", descending: true).snapshots(),
builder: (context,
AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
}
return PageView.builder( //to make the page scroll
itemCount: snapshot.data!.docs.length,/*the rest of the code*/);
and it shows an error in line
itemCount: snapshot.data!.docs.length,
saying Null check operator used on a null value
the database look like this
The error indicates that snapshot.data is null. This could happen when snapshot.connectionState is equal to ConnectionState.none when the stream is initialized and should be protected against.
Depending on how the PageView is set up you could handle this by changing that line to
itemCount: snapshot.data?.docs.length ?? 0,
which will pass 0 when snapshot.data is null.
Another way would be to check for the null value beforehand.
if (snapshot.data == null) {
return SomeWidget():
} else {
return PageView.builder( //to make the page scroll
itemCount: snapshot.data!.docs.length,/*the rest of the code*/
);
}

Expected a value of type 'Map<String, dynamic>', but got one of type 'Null'

I'm using flutter and managing data by cloud_firestore.
I could send data to firestore, but now I'm Struggling with reading data.
In firestore, data are stored like this;
"users" collection -> "(uid)" document -> "userName" string field
And this is the code which I trying.
Showing LinerProgressIndicator till snapshot has done.
CollectionReference users = FirebaseFirestore.instance.collection('users');
FutureBuilder(
future: users.doc().get(),
builder: (context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return const SizedBox(
width: 50,
child: LinearProgressIndicator(),
);
}
if (snapshot.hasError) {
return SelectableText(snapshot.error.toString());
}
if (!snapshot.hasData) {
return const Text('No data found');
}
Map<String, dynamic> data =
snapshot.data!.data() as Map<String, dynamic>;
return Text("User Name: ${data['userName']}");
},
)
But when snapshot done, error occurred.
Expected a value of type 'Map<String, dynamic>', but got one of type
'Null'
I referenced One-time Read item this official article
I have confirmed that the values ​​for 'users' -> uid -> 'userName' are correct.
Addition 1:
I debugged builder of FutureBuilder.
print('${snapshot.data!.data()}');
null
print('${snapshot.data}');
Instance of '_JsonDocumentSnapshot'
Addition 2:
#Saiful Islam
I rewrote the code.
Then other error occurred.
Expected a value of type 'Map<String, dynamic>', but got one of type '_JsonDocumentSnapshot'
Also, print() result is same as Addition 1.
test code;
CollectionReference users = FirebaseFirestore.instance.collection('users');
FutureBuilder(
future: users.doc(FirebaseAuth.instance.currentUser!.uid).get(),
builder: (context, AsyncSnapshot<DocumentSnapshot> snapshot) {
print('${snapshot.data!.data()}'); //null
print('${snapshot.data}'); //Instance of '_JsonDocumentSnapshot'
if (snapshot.connectionState != ConnectionState.done) {
return const SizedBox(
width: 50,
child: LinearProgressIndicator(),
);
}
if (snapshot.hasError) {
return SelectableText(snapshot.error.toString());
}
if (!snapshot.hasData) {
return const Text('No data found');
}
if (snapshot.connectionState == ConnectionState.done) {
Map<String, dynamic> data =
snapshot.data as Map<String, dynamic>;
return Text("User Name: ${data['username']}");
}
return const SelectableText("userName");
},
)
Addition 3:##
Added print('${jsonDecode(snapshot.data)}').
Error appears again.
Bad state: cannot get a field on a DocumentSnapshotPlatform which does
not exist
Detail of the error;
Launching lib\main.dart on Chrome in debug mode...
This app is linked to the debug service: ws://127.0.0.1:59027/fBobSNPxOzo%3D/ws
Debug service listening on ws://127.0.0.1:59027/fBobSNPxOzo=/ws
Running with sound null safety
Connecting to VM Service at ws://127.0.0.1:59027/fBobSNPxOzo=/ws
════════ Exception caught by widgets library ═══════════════════════════════════
The following StateError was thrown building FutureBuilder<DocumentSnapshot<Object?>>(dirty, state: _FutureBuilderState<DocumentSnapshot<Object?>>#330c8):
Bad state: cannot get a field on a DocumentSnapshotPlatform which does not exist
The relevant error-causing widget was
FutureBuilder<DocumentSnapshot<Object?>> FutureBuilder:file:///D:/FlutterProjects/testProject/lib/profile.dart:32:13
When the exception was thrown, this was the stack
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 251:49 throw_
packages/cloud_firestore_platform_interface/src/platform_interface/platform_interface_document_snapshot.dart 77:7 get
packages/cloud_firestore/src/document_snapshot.dart 92:48 get
packages/cloud_firestore/src/document_snapshot.dart 96:40 _get
packages/testProject/profile.dart 50:45 <fn>
packages/flutter/src/widgets/async.dart 782:48 build
packages/flutter/src/widgets/framework.dart 4782:27 build
packages/flutter/src/widgets/framework.dart 4665:15 performRebuild
packages/flutter/src/widgets/framework.dart 4840:11 performRebuild
packages/flutter/src/widgets/framework.dart 4355:5 rebuild
packages/flutter/src/widgets/framework.dart 2620:31 buildScope
packages/flutter/src/widgets/binding.dart 882:9 drawFrame
packages/flutter/src/rendering/binding.dart 319:5 [_handlePersistentFrameCallback]
packages/flutter/src/scheduler/binding.dart 1143:15 [_invokeFrameCallback]
packages/flutter/src/scheduler/binding.dart 1080:9 handleDrawFrame
packages/flutter/src/scheduler/binding.dart 996:5 [_handleDrawFrame]
C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/platform_dispatcher.dart 1003:13 invoke
C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/platform_dispatcher.dart 157:5 invokeOnDrawFrame
C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine.dart 440:45 <fn>
════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by rendering library ═════════════════════════════════
A RenderFlex overflowed by 99340 pixels on the bottom.
The relevant error-causing widget was
Column Column:file:///D:/FlutterProjects/testProject/lib/profile.dart:26:20
════════════════════════════════════════════════════════════════════════════════
What kind of problem can you think of?
Thank you.
You should only return Map of the document exists. However, you aren't checking if this condition is true or not.
To be safe, do not return data unless it's inside an if statement, which checks for hasData and then exists.
The error is also probably due to a spelling mistake. Double check that again.
But your error is from the start, with this line:
future: users.doc().get(),
You did not tell which document. You need to pass the id of the document when you run this query.
future: users.doc('0Cb43453fdsg4').get(), //This is an example 'id'.
This should help with your issue
future:
FirebaseFirestore.instance.collection("rates").doc(documentId).get(),
builder: ((context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
Map<String, dynamic> data =
(snapshot.data!.data()) as Map<String, dynamic>;
String specifiedData = '${data['specifiedData']}';
return Padding(
padding: const EdgeInsets.all(16.0),
child: Material()}}

Firestore returns 'instance of querysnapshot' even if the collection does not exists

StreamBuilder(
stream: Firestore.instance.collection('aaaaaaaaaaaaaaaa').snapshots(),
builder: ( context , snap){
if(snap.data == null){
print('A');
}
if(snap.data != null){
print(snap.data);
print('B');
}
Obviously collection ('aaaaaaaaaaaaaa') does not even exists then why it is not returning null?
Querying a non-existing (or empty) collection is not an error. So when there are no results, Firestore gives you an empty QuerySnapshot, instead of an error.
To detect if there were any results, check if the QuerySnapshot has any documents (FlutterFire doesn't seem to wrap the native QuerySnapshot.isEmpty() method.
You should use hasData to check if there is data or not:
StreamBuilder(
stream: Firestore.instance.collection('aaaaaaaaaaaaaaaa').snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasData) {
print("a");
} else{
return Text("No data");
}
return CircularProgressIndicator();
},
),

Firebase in flutter getCurrentUser never unwraps the Future and I can't get at the Data

So I have a Flutter app with Firebase authentication. I have a dart file for sign in and registration and then a separate dart file with different Widgets for a list of data. I want to get the current user so I can get that users personalized data from the database. But for some reason I can never get that user. Here is the code:
Future getUser() async {
final FirebaseUser user = await FirebaseAuth.instance.currentUser();
return user.getIdToken();
}
return FutureBuilder(
future: getUser(),
builder: (context, snapshot) {
if (snapshot.hasData) return Text(snapshot.data);
else if (snapshot.hasError) return Text("data error (see futurebuilder)");
return Text("Await for data");
},
);
But on my debugging device the Text output just says data error (see future builder) which is the error message I wrote. However I can't figure out what I'm doing wrong. I don't see why this isn't just giving me the user ID token. Thanks.
Try changing your code from snapshot.hasData to snapshot.connectionState == ConnectionState.done and see if this helps you. I have the exact same setup in my app and this works for me.
something like this should work
FutureBuilder(
future: getUser(),
builder: (context, snapshot) {
if(snapshot.connectionState == ConnectionState.done){
return
//Execute code after future is returned
} else {
return CircularProgressIndicator();
}
},
);

usernames in google auth flutter

I am facing the following problem: I am displaying the username of the google account of the user in a subtitle in a list tile, but the code that I use displays an error if the user is not logged in first, so how can I edit this code to display you are not logged in when the user is not logged in or is logged out. Also, how to display the username of the google account if the user is signed in or changed his account this is the code:
subtitle: new FutureBuilder<FirebaseUser>(
future: FirebaseAuth.instance.currentUser(),
builder: (BuildContext context,AsyncSnapshot<FirebaseUser> snapshot){
if (snapshot.connectionState == ConnectionState.waiting) {
return new Text(snapshot.data.displayName);
}
else {
return new Text('you are not logged in');
}
},
Fixing the problem
You can simply replace snapshot.connectionState == ConnectionState.waiting with snapshot.hasData, which is the equivalent of snpashot.data != null. This, however, will display 'you are not logged in' even when still waiting. I added a 'loading' Text for waiting:
builder: (BuildContext context, AsyncSnapshot<FirebaseUser> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Text('loading');
} else if (!snapshot.hasData) {
return Text('you are not logged in');
} else {
return Text(snapshot.data.displayName);
}
}
This works because currentUser() returns null if there is no current user.
A suggestion
You are currently using currentUser(), which does not update on authentication changes. You can use onAuthStateChanged, which is a stream that will update every time and always provide you with the latest user. For this, you will have to migrate to StreamBuilder:
subtitle: StreamBuilder(
stream: FirebaseAuth.instance.onAuthStateChanged,
builder: (BuildContext context, AsyncSnapshot<FirebaseUser> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Text('loading');
} else if (!snapshot.hasData) {
return Text('you are not logged in');
} else {
return Text(snapshot.data.displayName);
}
},
)

Resources