firebase / flutterfire

πŸ”₯ A collection of Firebase plugins for Flutter apps.
https://firebase.google.com/docs/flutter/setup
BSD 3-Clause "New" or "Revised" License
8.65k stars 3.96k forks source link

[cloud_firestore]: Double is not a subtype of int #12756

Open larssn opened 4 months ago

larssn commented 4 months ago

Is there an existing issue for this?

Which plugins are affected?

Core

Which platforms are affected?

Android

Description

So I've just run into the issue described in #12436, and this is using cloud_firestore_platform_interface: 6.2.2.

The "fix" was changing the int directly in firestore (away from 0 and back to 0), which caused the issue to go away.

Reproducing the issue

Not sure, I'm just FieldValue.increment(ing) integers with integers.

Firebase Core version

2.30.1

Flutter Version

3.19.6

Relevant Log Output

No response

Flutter dependencies

Workspace Environment ```text Dart Code extension: 3.88.0 Flutter extension: 3.88.0 (activated) App: Visual Studio Code App Host: desktop Version: mac 1.89.0 Workspace type: Flutter (LSP) Dart (3.3.4): /Users/lars/fvm/versions/stable/bin/cache/dart-sdk Flutter (3.19.6): /Users/lars/fvm/versions/stable (SM T510 (android-arm/android)) ```
Output from 'dart info' `/Users/lars/fvm/versions/stable/bin/cache/dart-sdk/bin/dart info` If providing this information as part of reporting a bug, please review the information below to ensure it only contains things you're comfortable posting publicly. #### General info - Dart 3.3.4 (stable) (Tue Apr 16 19:56:12 2024 +0000) on "macos_arm64" - on macos / Version 14.4.1 (Build 23E224) - locale is en-US #### Project info - sdk constraint: '>=3.3.3 <4.0.0' - dependencies: android_id, audioplayers, bloc, built_collection, built_value, cached_network_image, cloud_firestore, cloud_firestore_platform_interface, collection, country_pickers, crypto, dart_date, decimal, device_info_plus, expansion_widget, file_picker, firebase_analytics, firebase_auth, firebase_core, firebase_crashlytics, firebase_storage, firebase_ui_firestore, flutter, flutter_bloc, flutter_dotenv, flutter_html, flutter_keyboard_visibility, flutter_localizations, flutter_material_color_picker, flutter_nfc_kit, flutter_riverpod, flutter_slidable, flutter_timezone, geography, html_unescape, http, image, image_picker, in_app_update, internet_connection_checker, intl, meta, package_info_plus, path_provider, phone_numbers_parser, pointycastle, positioned_tap_detector_2, qr_flutter, random_string, rational, reorderables, retry, rxdart, shared_preferences, sprintf, time, timezone, url_launcher, uuid, validators, xml - dev_dependencies: build_runner, built_value_generator, flutter_lints - elided dependencies: 13 #### Process info | Memory | CPU | Elapsed time | Command line | | ------: | ---: | -----------: | ----------------------------------------------------------------------------------------- | | 62 MB | 0.0% | 49:23 | dart devtools --no-launch-browser | | 25 MB | 0.0% | 19:55:12 | dart devtools --no-launch-browser | | 4652 MB | 0.0% | 19:07:10 | dart language-server --protocol=lsp --client-id=VS-Code --client-version=3.88.0 | | 63 MB | 0.0% | 19:07:10 | flutter_tools.snapshot daemon | | 253 MB | 0.0% | 50:09 | flutter_tools.snapshot run --machine --start-paused -d R52N70RYCGL --target lib/main.dart |
Output from 'flutter doctor' `/Users/lars/fvm/versions/stable/bin/flutter doctor -v` ```text [βœ“] Flutter (Channel stable, 3.19.6, on macOS 14.4.1 23E224 darwin-arm64, locale en-US) β€’ Flutter version 3.19.6 on channel stable at /Users/lars/fvm/versions/stable β€’ Upstream repository https://github.com/flutter/flutter.git β€’ Framework revision 54e66469a9 (3 weeks ago), 2024-04-17 13:08:03 -0700 β€’ Engine revision c4cd48e186 β€’ Dart version 3.3.4 β€’ DevTools version 2.31.1 [βœ“] Android toolchain - develop for Android devices (Android SDK version 34.0.0) β€’ Android SDK at /Users/lars/Library/Android/sdk β€’ Platform android-34, build-tools 34.0.0 β€’ ANDROID_HOME = /Users/lars/Library/Android/sdk β€’ Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java β€’ Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11572160) β€’ All Android licenses accepted. [βœ“] Xcode - develop for iOS and macOS (Xcode 15.3) β€’ Xcode at /Applications/Xcode.app/Contents/Developer β€’ Build 15E204a β€’ CocoaPods version 1.15.2 [βœ“] Chrome - develop for the web β€’ Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [βœ“] Android Studio (version 2023.3) β€’ Android Studio at /Applications/Android Studio.app/Contents β€’ Flutter plugin can be installed from: πŸ”¨ https://plugins.jetbrains.com/plugin/9212-flutter β€’ Dart plugin can be installed from: πŸ”¨ https://plugins.jetbrains.com/plugin/6351-dart β€’ Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11572160) [βœ“] VS Code (version 1.89.0) β€’ VS Code at /Applications/Visual Studio Code.app/Contents β€’ Flutter extension version 3.88.0 [βœ“] Connected device (5 available) β€’ A920Pro (mobile) β€’ 1851510595 β€’ android-arm β€’ Android 8.1.0 (API 27) β€’ SM T510 (mobile) β€’ R52N70RYCGL β€’ android-arm β€’ Android 11 (API 30) β€’ Another Phone (mobile) β€’ 00008110-000404840C7A801E β€’ ios β€’ iOS 17.4.1 21E236 β€’ macOS (desktop) β€’ macos β€’ darwin-arm64 β€’ macOS 14.4.1 23E224 darwin-arm64 β€’ Chrome (web) β€’ chrome β€’ web-javascript β€’ Google Chrome 124.0.6367.119 [βœ“] Network resources β€’ All expected network resources are available. β€’ No issues found! ```

Additional context and comments

No response

TarekkMA commented 4 months ago

Hello @larssn, thank you for reporting this issue. I wasn't able to reproduce it. Here's the code I used, and it ran without errors:

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  FirebaseFirestore.instance.settings = const Settings(
    persistenceEnabled: true,
  );
  if (shouldUseFirestoreEmulator) {
    FirebaseFirestore.instance.useFirestoreEmulator('localhost', 8080);
  }

  runApp(TheApp());
}

class TheApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: ElevatedButton(
            onPressed: () async {
              try {
                // Update operation
                FirebaseFirestore firestore = FirebaseFirestore.instance;
                DocumentReference documentReference =
                firestore.collection('test_10153').doc('counter');
                final doc = await documentReference.get();
                if (!doc.exists) {
                  await documentReference.set(<String, dynamic>{});
                }
                await documentReference.update({'counter': FieldValue.increment(1)});

                // Attempt to fetch and deserialize the updated document
                DocumentSnapshot snapshot = await documentReference.get();
                Map<dynamic, dynamic>? data = snapshot.data() as Map<dynamic, dynamic>?;
                if (data != null) {
                  // Directly deserialize 'counter' field within fromFirestore
                  int? counter = data['counter'] as int?;
                  print('Deserialized counter value: $counter');
                }
              } on Exception catch (error, stackTrace) {
                debugPrint(error.toString());
                debugPrintStack(stackTrace: stackTrace);
              }
            },
            child: Text('Increment Counter and Deserialize'),
          ),
        ),
      ),
    );
  }
}

I suggest you update all your plugins to the latest version and try again. If the issue still persists, please provide a reproduction code or repo that is failing.

larssn commented 4 months ago

They are all the latest version, and I just experienced this issue today.

And I have used FieldValue.increment without issues, but the error seems periodic.

TarekkMA commented 4 months ago

What's the size of the vlaue you are trying to increment and by how much you are incrementing it?

larssn commented 4 months ago

Not much, in my tests I used about -5 to +5. And the size incremented/subtracted, is about the same.

minhdanh commented 4 months ago

I'm seeing a kind of similar issue:

_TypeError: type 'int' is not a subtype of type 'double' in type cast

This happens at this line:

    final double graceAmount = snap.get('grace_amount') != null ? snap.get('grace_amount') as double : 0;

The thing is this still works fine for most of my users. Meaning snap.get('grace_amount') returns 0.0 for most of them. But yesterday when I tried to copy all the documents of a user to another, the new user encounter this issue. For this case snap.get('grace_amount') returns 0. So I guess something has changed from firestore end.

This is the firebase function that I used:

    const { sourceUserID, destUserID } = request.body;

    if (!sourceUserID || !destUserID) {
      logger.warn("Missing sourceUserID or destUserID.");
      response.sendStatus(400);
    }
    try {
      const sourceRef = getFirestore().collection("users").doc(sourceUserID);
      const destRef = getFirestore().collection("users").doc(destUserID);

      // Copy subcollections
      const sourceCollections = await sourceRef.listCollections();
      for (const collection of sourceCollections) {
        const collectionRef = sourceRef.collection(collection.id);
        const destCollectionRef = destRef.collection(collection.id);

        const collectionSnapshot = await collectionRef.get();
        for (const doc of collectionSnapshot.docs) {
          await destCollectionRef.doc(doc.id).set(doc.data(), { merge: true });
        }
      }
      logger.info("Documents copied successfully");
    } catch (error) {
      logger.error("Error copying documents");
    }
minhdanh commented 4 months ago

I guess I figured it out. Using Typescript/Javascript, it was impossible for me to explicitly use a double type for numbers without the fractional part, like 0, 10, 123, etc. I was able to do that with Dart, that's why my normal users don't experience the problem. Furthermore the Firebase consol only shows the values as "number" is something that made it more confusing to me when there're actually 2 types of number supported: https://firebase.google.com/docs/firestore/manage-data/data-types

I had to use a Python function to do the copy. Problem fixed.

TarekkMA commented 4 months ago

@minhdanh Thank you for sharing these details, appreciated.


@larssn Can you investigate if your issue is similar to the one @minhdanh mentioned? Since I couldn't get issue to happen when testing.

larssn commented 4 months ago

Ours is in pure dart, no web involved, so I doubt it's the same issue.

The "fix" was changing the int directly in firestore (away from 0 and back to 0), which caused the issue to go away.

I still think this part was weird, and is probably significant.

Tr736 commented 4 months ago

for me I simply us num instead of int and then num.toInt()

larssn commented 4 months ago

We use the workaround on incoming data as well, but I'd prefer we wouldn't have to.

rogerfsg commented 3 months ago

Today, the DocumentSnapshotData is reading every int as double.

Like, "x": 1,

its giving on the runtime x=1.0