Skip to content
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

[Bug]: DeviceInfoPlugin.webBrowserInfo fails locally on Safari #3391

Closed
8 tasks done
sergioprot opened this issue Dec 10, 2024 · 3 comments · Fixed by #3401
Closed
8 tasks done

[Bug]: DeviceInfoPlugin.webBrowserInfo fails locally on Safari #3391

sergioprot opened this issue Dec 10, 2024 · 3 comments · Fixed by #3401
Labels
bug Something isn't working triage

Comments

@sergioprot
Copy link

Platform

Web

Plugin

device_info_plus

Version

11.1.1

Flutter SDK

3.24.5

Steps to reproduce

Write a Flutter app that uses device_info_plus plugin to get web browser info.

Run web server locally on a macOS device:

flutter run -d web-server --web-hostname 0.0.0.0 --web-port 8080

Open a Flutter app on a Safari browser locally. A TypeError is thrown. The error does not occur in a --release build though.

Code Sample

import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/material.dart';

Future<void> main() async {
  try {
    DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
    WebBrowserInfo webBrowserInfo = await deviceInfo.webBrowserInfo;
    print('Running on ${webBrowserInfo.userAgent}');
  } on TypeError catch (e, stacktrace) {
    print(e);
    print(stacktrace);
  }
  runApp(const MaterialApp(
    home: Scaffold(),
  ));
}

Logs

[Log] TypeError: null: type 'Null' is not a subtype of type 'double' (dart_sdk.js, line 38043)
[Log] dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 247:26  DartError (dart_sdk.js, line 38043)
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 296:28  throw_
dart-sdk/lib/_internal/js_shared/lib/rti.dart 1405:3                          _failedAsCheck
dart-sdk/lib/_internal/js_shared/lib/rti.dart 1383:3                          _generalAsCheckImplementation
packages/device_info_plus/src/device_info_plus_web.dart.js 50:399             deviceInfo
packages/device_info_plus/device_info_plus.dart.js 92:146                     webBrowserInfo
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 84:54            runBody
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 127:12           _async
packages/flutter_input_test/main.dart.js 262:47                               main
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 84:54            runBody
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 127:12           _async
lib/ui_web/ui_web/initialization.dart 41:15                                   <fn>
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 45:50            <fn>
dart-sdk/lib/async/future_impl.dart 861:44                                    handleValueCallback
dart-sdk/lib/async/future_impl.dart 890:32                                    _propagateToListeners
dart-sdk/lib/async/future_impl.dart 666:5                                     <fn>
dart-sdk/lib/async/future_impl.dart 736:7                                     <fn>
dart-sdk/lib/async/schedule_microtask.dart 40:11                              _microtaskLoop
dart-sdk/lib/async/schedule_microtask.dart 49:5                               _startMicrotaskLoop
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 181:15           <fn>

Flutter Doctor

[✓] Flutter (Channel stable, 3.24.5, on macOS 15.1 24B83 darwin-arm64, locale en-LV)
    • Flutter version 3.24.5 on channel stable at /Users/sergey/Developer/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision dec2ee5c1f (4 weeks ago), 2024-11-13 11:13:06 -0800
    • Engine revision a18df97ca5
    • Dart version 3.5.4
    • DevTools version 2.37.3

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.1)
    • Android SDK at /Users/sergey/Library/Android/sdk
    • Platform android-34, build-tools 33.0.1
    • ANDROID_HOME = /Users/sergey/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.11+0-17.0.11b1207.24-11852314)
    • All Android licenses accepted.

Checklist before submitting a bug

  • I searched issues in this repository and couldn't find such bug/problem
  • I Google'd a solution and I couldn't find it
  • I searched on StackOverflow for a solution and I couldn't find it
  • I read the README.md file of the plugin
  • I'm using the latest version of the plugin
  • All dependencies are up to date with flutter pub upgrade
  • I did a flutter clean
  • I tried running the example project
@sergioprot sergioprot added bug Something isn't working triage labels Dec 10, 2024
@miquelbeltran
Copy link
Member

miquelbeltran commented Dec 10, 2024

type 'Null' is not a subtype of type 'double'

It's a strange issue, the only property that is a double? is the deviceMemory which is already nullable: https://github.com/fluttercommunity/plus_plugins/blob/main/packages/device_info_plus/device_info_plus/lib/src/model/web_browser_info.dart

@davidequadrelli-b
Copy link

davidequadrelli-b commented Dec 13, 2024

@miquelbeltran We are having the same issue also with Chrome sometimes. I don't know why sometimes the deviceMemory property is missing from navigator, but the problem seems to be in the web package:

https://github.com/dart-lang/web/blob/3619fd8391b32ddde18a1ca441b288ff3c39f524/web/lib/src/dom/html.dart#L12018

Here deviceMemory is defined as a double and not a double?, so when the value is missing, accessing the property throws an error. Even if the device_info_plus plugin has a nullable interface, the fact that the underlying web library is not nullable is the real problem.

We tested the following code and this could be a temporary fix for the library. With the following extension

extension SafeNavigationGetterExtensions on html.Navigator {
  double? safeDeviceMemory() {
    try {
      return deviceMemory;
    } catch (e) {
      return 0.0;
    }
  }
}

we can change the DeviceInfoPlusWebPlugin class in the device_info_plus_web.dart file to use the new safe getter:

@override
  Future<BaseDeviceInfo> deviceInfo() {
    return Future<WebBrowserInfo>.value(
      WebBrowserInfo.fromMap(
        {
          'appCodeName': _navigator.appCodeName,
          'appName': _navigator.appName,
          'appVersion': _navigator.appVersion,
          'deviceMemory': _navigator.safeDeviceMemory(),
          'language': _navigator.language,
          'languages': _navigator.languages,
          'platform': _navigator.platform,
          'product': _navigator.product,
          'productSub': _navigator.productSub,
          'userAgent': _navigator.userAgent,
          'vendor': _navigator.vendor,
          'vendorSub': _navigator.vendorSub,
          'hardwareConcurrency': _navigator.hardwareConcurrency,
          'maxTouchPoints': _navigator.maxTouchPoints,
        },
      ),
    );

This solution can be used also for fixing other fields with the same problem.

Do you think this fix can be integrated in the package?

@miquelbeltran
Copy link
Member

Yes, thanks for researching this, feel free to submit a PR with the change

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working triage
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants