Closed MostHated closed 4 years ago
I'm not sure you can mix await
with catchError
.
In any case this seems to be a general dart issue rather than specific to Firedart, so I'd encourage you to try StackOverflow.
Unfortunately I don't have the time, and sometimes the knowledge to answer these types of questions. I also prefer to keep this issue tracker focused on Firedart issues rather than general programming questions.
I understand what you are saying, but I feel like either FirebaseAuth.initialize(data.getString('apiKey'), hiveStore);
or auth.getUser()
should be returning back a USER_NOT_FOUND or something if attempting to use the token store information of a user that does not exist in Firebase instead of making it all the way to return User.fromMap(map['users'][0]);
and throwing a null error?
flutter: │ NoSuchMethodError: The method '[]' was called on null.
flutter: │ Receiver: null
flutter: │ Tried calling: [](0)
flutter: ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
flutter: │ #0 dart:core Object.noSuchMethod
flutter: │ #1 package:firedart/auth/user_gateway.dart 17:37 UserGateway.getUser
flutter: │ #2 ===== asynchronous gap ===========================
flutter: │ #3 dart:async _asyncThenWrapperHelper
flutter: │ #4 package:firedart/auth/firebase_auth.dart 70:42 FirebaseAuth.getUser
I tried to see if there was something I could do about it, but in the situation of a user being deleted from firestore, but still remaining in the client token store, I tried several different ways to catch it but it always dies out in auth.getUser(), though.
try {
user = auth.getUser();
} on Exception catch (e) {
FBError.exceptionToUiMessage(e);
return null;
}
Thanks, -MH
I see what you mean. getUser should fail if the token isn't valid before trying to read the map. I'll reopen the ticket to look into that.
I'm also facing this exact issue in my Dartbase Admin SDK project. I have not narrowed down the issue just yet, but I will tell you it has nothing to do with tokenstore. I nuked token store completely from in my project. It is a direct call from my _post (or firedart's _auth) method. The direct api call to google servers is returning the empty map.
I'm investigating.
I would also like to note an observation I've made. My test classes always succeed when my firebase account was created by email/pass. It seems to be failing when it's a google sign-in. I know it sounds stupid because it's a very strict and simple database on firebase auth's end. But it's what I observed.
I've been using firedart to sign my account in my tests so I can generate an ID token to pass to my dartbase admin sdk project as user authentication. Firedart only supports email/pass so I'm forced to delete my account and sign up again by email/pass. Then I'm forced to update my account details to add a displayname (optionally a profilepic as well) so my UserRecord object doesn't throw a nullpointer.
Other than that, if I'm signed in by email/pass and add a displayname, then generate an id token with firedart, and then call any method that triggers a getUser request, it succeeds in my test classes.
If I do the same in my flutter app (via android emulator) and register my account as a google sign in, then it seems to start failing for some reason, with the reason being that it can't find the user.
My current ongoing theory is the difference between these APIs: https://cloud.google.com/identity-platform/docs/reference/rest/v1/projects.accounts/lookup vs. https://firebase.google.com/docs/reference/rest/auth#section-get-account-info But I can easily be very wrong.
@cachapa What do you think? We're both using the gcloud api (first link) instead of the firebase api (second link). I normally agree that they're essentially the same, the firebase one just falls back to the gcloud one, but that's in theory.
EDIT: I also looked at firebase_admin's code and they're doing the exact same thing we're doing except for passing [uid] as an array instead of a direct string. I tried that and it threw a bad request error directly so that is not the problem. Other than that, almost identical requests
EDIT: After deleting my account again, signing out of firebase, and trying again, it seems to be working. This issue is very sporadic. I'll eventually narrow it down with time as it happens.
EDIT: Example:
I/flutter (22198): Exception: User not found with id [yBIMudSuMsZVpcCB67hZgdADQLq2]
(I've verified the IDs are identical)
Thanks for the report. There were two issues here:
I'll publish a new version on pub.dev later today.
@cachapa I don't think you nailed the cause of the problem.
The response is already 200, if it weren't, the old != 200 line would've caught it and said something, but it doesn't and continues to jsonDecode.
I might be wrong, but google might send a 200 code anyways and an error object inside the array list for each user in the batchGet request.
Moreover you're not catching any exceptions in user_gateway which I mentioned the issue arose from https://github.com/cachapa/firedart/blob/0eb2fec4ccc41bc2ed94d21e2a71605ff9248a0f/lib/auth/user_gateway.dart#L42-L45
My code: https://github.com/SwissCheese5/Dartbase-Admin-SDK/blob/master/lib/auth/user_gateway.dart#L13-L19
Future<UserRecord> getUserById(String uid) async {
var map = await _post('lookup', {'localId': uid});
if (!map.containsKey('users')) {
throw Exception('User not found with id [$uid]');
}
return UserRecord.fromJson(map['users'][0]);
}
That exception is thrown. It's a 200 response code with an empty map.
I'm not sure what you mean. Can you tell me how to reproduce a situation where the response is 200 but the user payload is empty? In my tests all errors return 400. I even made some unit tests for that.
I'm a bit confused by your earlier message since you mention Google Signin which Firedart doesn't support. This might be an issue that's only present on your fork.
Moreover you're not catching any exceptions in user_gateway which I mentioned the issue arose from
This isn't necessary since the exception is being thrown from the client itself.
Figured it out. It's problems with firebase auth and google sign in. (flutter plugins)
@MostHated Here's my sign in code if you're interested. I was getting a null id token from an outdated currentUser object from FirebaseAuth
Future<void> signInWithGoogle() async {
GoogleSignInAccount gUser = googleSignIn.currentUser;
if (gUser == null) {
gUser = await googleSignIn.signInSilently();
}
if (gUser == null) {
gUser = await googleSignIn.signIn();
}
final GoogleSignInAuthentication googleAuth = await gUser.authentication;
final AuthCredential credential = GoogleAuthProvider.getCredential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
final FirebaseUser user = (await _auth.signInWithCredential(credential)).user;
assert(user.email != null);
assert(user.displayName != null);
assert(!user.isAnonymous);
assert(await user.getIdToken() != null);
firebaseUser = user;
_firebaseUserController.add(firebaseUser);
assert(user.uid == firebaseUser.uid);
}
I was wanting to test out dart 2.6's extensions, so I whipped this up:
extension StringNullCheck on String {
bool get isNullOrEmpty => this == '' || this == null;
}
I was going to try and use it to check map['users']
but then I saw what you had in your prior post (if (!map.containsKey('users'))
), which made much more sense to use anyways for this particular issue.
I reworked some of my other code, such as my silent and standard login, which seems to be mostly ok now, but I have not tested it much yet. Getting the official return from Google of "USER_NOT_FOUND" is ideal, as my error checking class was created to match the errors that Google would return.
I am currently only using email/password authentication, so I don't need to worry too much about the GoogleAuthProvider specific portion of it unless I decide to add that in later.
Hey there, I am having some issues trying to catch and process errors. I have an error class I had been using to catch errors and return UI/log messages with some things like the following:
I ran into my first error though when testing some things, but it died out in UserGateway.getUser() with a forced breakpoint in Android Studio:
I had deleted my user from Firebase, then restarted my app without having performed the SignOut() function within the package, so the user information was still within the Hive storage, so when it went to start back up and silently log in, it caused an error, but it wasn't caught by my catchError, and so far none of them have been able to be caught when I have tried (ex. incorrect password, etc).
This was what I was attempting to do. Is there some other way I am supposed to go about handling this? I feel like I might be missing something.
Thanks, -MH