-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Behaviour of promiseToFuture
has changed from Dart SDK => 3.0.0 (Flutter >=3.10.0)
#52572
Comments
@russellwheatley - Thanks for reaching out and sharing all the details! From the issue in the flutterfire repo, it appears to me that this discrepancy is visible only during development. Do you know if it is also visible in production/release code? I ask because we have 2 different compilers at play, when using Also any help creating a smaller repro we can try locally would be super useful. I tried coping the sample from the flutterfire issue tracker, but the code is missing a few imports so I haven't yet been able to reproducable locally. If it's at all possible to create a simpler Dart program that doesn't use flutter to reproduce this, that would be ideal. Thanks in advance! FYI @srujzs in case this kind of behavior change seems related to any of our recent changes in this area. To be honest, I am not sure yet whether this is a web-libraries issue, or a ddc issue. |
I think this is unrelated to I am a little confused on how you were seeing @JS('Error')
@staticInterop
abstract class AuthError {}
extension AuthErrorExtension on AuthError {
external String get code;
external set code(String s);
external String get message;
external set message(String s);
external String get email;
external set email(String s);
external AuthCredential get credential;
external set credential(AuthCredential c);
external String get tenantId;
external set tenantId(String s);
external String get phoneNumber;
external set phoneNumber(String s);
} to see if that allows you to interact with it? I'm also a little confused on what type checks you were doing before that are now failing. A repro and/or a log of the exception and related code would help here if possible, thanks! |
Ah, I see, thanks for pointing that out @srujzs. @russellwheatley - can you point us closer to where you see a change in behavior in the firebase package? For example, I found this conversion between JS errors to Dart errors here: https://github.com/firebase/flutterfire/blob/81f1b80c445cfaab3e7752b8c58f35c92d234d8d/packages/firebase_auth/firebase_auth_web/lib/src/utils/web_utils.dart#LL25-L30 Is that where you see a change in behavior (the true branch is taken in 3.0.0 but the false branch was taken in the previous SDK)? Looking at that code, I wonder if something wrong is surfacing with that NativeError is in a strange position because it was always known to Dart, it changed where it is in the type hierarchy, but it didn't change how we interpret it. While I can imagine that a change to the NativeError hierarchy could affect the result of |
Thanks for the quick response! @srujzs - I tried making it a I thought the easiest way to demonstrate is to update the auth example on the FlutterFire repo. Steps to reproduce: This is the branch you need to use: https://github.com/firebase/flutterfire/tree/auth-10966
Which I am printing here: https://github.com/firebase/flutterfire/compare/auth-10966?expand=1#diff-a522fde29aeb319e6149a657c49c90dcce5c910e0e1166a1b37a0f00b4360885R28
If you want to see the instance type for yourself, you may add a checkpoint here. Check out the instance type. You will see |
Thanks @russellwheatley for all the details. I'm still curious about the behavior in release mode. Based on the fact that What's really strange here is that the dev-mode behavior in 3.10 is more consistent with how the compiler's runtime was written (even how it was written in 3.7). One theory we haven't explored is that potentially flutter changed how the .html loads the firebase and Dart code. It is quite possible that our output is sensitive to the order in which the code loaded. While we still need to investigate why the behavior changed, what I notice here is that firebase was accidentally working because of some internal compiler representation choices. I'd recommend making a couple changes to firebase to make it more robust and ensure it doesn't indirectly depend on implementation details. The pointers you share match exactly my suspicion that the issue is surfaced at
Some rationale for why:
To replace the import 'dart:js_util' as js_util;
import 'package:js/js.dart';
@JS('firebase_core.FirebaseError')
Object get firebaseErrorType;
...
FirebaseAuthException getFirebaseAuthException(
Object exception, [
auth_interop.Auth? auth,
]) {
if (!js_util.instanceof(exception, firebaseErrorType)) { ...
|
Seems I made a mistake in my local testing last Friday, but I actually have a minimal repro we can use here: This program: import 'package:js/js.dart';
@JS()
@anonymous
class L1 {}
@JS()
external Object get o1;
@JS()
external void eval(String s);
const String jsCode = r'''
self.FirebaseError = class FirebaseError extends Error {}
self.o1 = new FirebaseError("boo");
''';
main() async {
eval(jsCode);
final o = o1;
print('${o.runtimeType}: ${o is L1}');
} Prints something different on each runtime and version:
It appears that the change to the |
I found the cause: the @nshahan - seems the use of NativeError in the SDK is very limited and only to check whether we have a TypeError (that we map to a JSNoSuchMethodError). It appears that in the dart2js runtime we direclty use Next steps:
|
Right, if it no longer gets intercepted as a special type, it can be interoperable for our purposes. It does look like dwds depends on some of this behavior: https://github.com/dart-lang/webdev/blob/b10d62b83288f92560bf9c05a06c4dc0a3cf84e8/dwds/lib/src/debugging/metadata/class.dart#L223, but that looks refactorable to |
I've created an issue to track on the FF repository to track the refactor needed for removing |
Thanks @russellwheatley - happy to look at your PR, in case we can help figure out why the fix didn't work on your end. |
Hey @sigmundch, I have created a demonstration PR which shows how we are not able to capture a This isn't just a problem with Auth but also Firestore and presumably all plugins on the web platform. I've shown what is happening in the PR description. This is fairly critical for FlutterFire so if you have any other suggestions, I'd be very grateful. Thanks. |
Hi @russellwheatley, thank you so much for creating that demonstration PR showing the issue! I was able to run it locally and see the issue first hand. It was extremely helpful! I better understand why the suggestion didn't work as expected. There are actually a lot of issues at play at once. I created a new branch that, I hope, addresses all of them here: sigmundch/flutterfire@master...additional_fixes I hope this unblocks you! Just so you know. We do intend to make changes in DDC to revert the NativeError behavior, that said it will take us time to land it properly. I still believe the fixes above would be a better approach: your package will be more robust as a result. Here is a summary of the issues:
In particular: issue 1 is what we discussed earlier. The If we switched The Possible fixes here are to either:
I prefer (a), but I cannot demonstrate that, so I implemented (b) in my changes. (b) is more permissive than (a), but much more restricted than the original The third issue is similar to the first. The cast to With the proposed changes, I can run the example a bit further, but then I get a null safety error (the email getter returns null). I expect that is just due to the nature of the sample, not because of issues related to interop anymore. If that's not the case, let me know and I'm happy to look further. |
This tracker is for issues related to:
Dart core library
dart:js_util.dart
Dart SDK Version (
dart --version
)Dart 3.0.0
Whether you are using Windows, MacOSX, or Linux (if applicable)
MacOSX version 12.5.1
Whether you are using Chrome, Safari, Firefox, Edge (if applicable)
Chrome version 113.0.5672.126
We have an issue on the FlutterFire repository that you can read about here.
We use the
dart:js_util
promiseToFuture API to make async calls to the Firebase web JS SDK.In previous versions of Flutter (e.g. version 3.7.3 which uses the Dart SDK 2.19.2), we were able to access the underlying JS exception. You can see our implementation here. When the exception would come through, it would be an instance of
LegacyJavaScriptObject
. This allowed us to access the properties of the Firebase Auth exception.In the latest Flutter stable version 3.10.0 which uses Dart SDK 3.0.0, we now see
NativeError
instance come through as the exception. This doesn't allow us to access the properties we need for the Firebase Auth exception. It also doesn't allow us to do a type check on the exception instance as theNativeError
appears to be hidden as an internal implementation on the Dart SDK.Is there any way around this or a solution you propose?
The text was updated successfully, but these errors were encountered: