Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

[cloud_firestore][Windows] Transaction read and commit errors lose the Firestore error code (reported as `unknown`)

Aperta Adatta ai principianti
#18,735 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
84/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
dart

Direzione di ricerca

Inizia in windows/cloud_firestore_plugin.cpp, in TransactionGet e nel gestore del completamento della transazione, confrontando entrambi i percorsi con ParseError. Riproduci il problema su Windows usando regole che negano le letture e verifica che le letture delle transazioni e i commit falliti riportino il codice di errore e il messaggio di Firestore invece di unknown. Conferma la modifica con l'esempio Dart di transazione fornito e i controlli pertinenti del plugin Windows.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Needs Attention platform: windows plugin: cloud_firestore reproduced type: bug
Is there an existing issue for this?
  • I have searched the existing issues.

This is the same class of defect as #18550 (firebase_database on Windows), in cloud_firestore.

Which plugins are affected?

Other (Cloud Firestore)

Which platforms are affected?

Windows

Description

On Windows, a Firestore transaction that fails reaches Dart as FirebaseException(code: 'unknown') whatever Firestore actually returned. The same failure on a plain DocumentReference.get() reports the real code (permission-denied, unavailable, …), because that path goes through ParseError.

Two paths in windows/cloud_firestore_plugin.cpp build their error without the details map that ParseError provides:

  1. TransactionGet, a read inside a transaction (L1260 at a646d55):

    result(FlutterError(error_message));
    

    That is the one-argument constructor, so the Firestore message lands in the error's code slot, with no message and no details.

  2. The transaction completion handler, when the commit fails (L1160):

    SendErrorOnPlatformThread(events_state_, "transaction_error",
                              completed_future.error_message(),
                              flutter::EncodableValue());
    

_flutterfire_internals' platformExceptionToFirebaseException reads the code only from details['code'] and falls back to unknown. It reads the message from details['message'], or else PlatformException.message. So:

  • a failed transaction read becomes [cloud_firestore/unknown] with an empty message, because the real message went into PlatformException.code, which is discarded;
  • a failed commit becomes [cloud_firestore/unknown], keeping the message but not the code.

Apps can't tell a rules or App Check refusal (permission-denied) from contention (aborted) or a transient network failure. Anything that retries or reports on the code misclassifies it: we retried a permanent permission-denied as if it were transient.

Observed: the read path in production, from a Windows desktop app. The stack ran through FirebaseFirestoreHostApi.transactionGet → MethodChannelTransaction.get and ended in FirebaseException: [cloud_firestore/unknown] with no message. Earlier in the same session, the same account's plain get() of another document failed with [cloud_firestore/permission-denied]. The commit path is from reading the code; it has the same shape.

Suggested fix (not yet compiled on Windows), giving both paths the shape ParseError already uses:

@@ TransactionStreamHandler completion
           } else {
+            EncodableMap details;
+            details[EncodableValue("code")] =
+                EncodableValue(CloudFirestorePlugin::GetErrorCode(
+                    static_cast<firebase::firestore::Error>(
+                        completed_future.error())));
+            details[EncodableValue("message")] =
+                EncodableValue(completed_future.error_message());
             SendErrorOnPlatformThread(events_state_, "transaction_error",
                                       completed_future.error_message(),
-                                      flutter::EncodableValue());
+                                      EncodableValue(details));
           }
@@ void CloudFirestorePlugin::TransactionGet(
   if (error_code != Error::kErrorOk) {
-    result(FlutterError(error_message));
+    EncodableMap details;
+    details[EncodableValue("code")] = EncodableValue(GetErrorCode(error_code));
+    details[EncodableValue("message")] = EncodableValue(error_message);
+    result(FlutterError("firebase_firestore", error_message, details));
   } else {
Reproducing the issue

On Windows, with rules that deny reading a document:

match /denied/{doc} { allow read: if false; }
try {
  await FirebaseFirestore.instance.runTransaction((tx) async {
    await tx.get(FirebaseFirestore.instance.doc('denied/doc'));
  });
} on FirebaseException catch (e) {
  print('${e.code}: ${e.message}');
}
  • Expected: permission-denied: Missing or insufficient permissions., as the same read outside a transaction reports.
  • Actual: unknown: (empty message).

A transaction whose write is denied by rules shows the commit path: the code is unknown and the message is kept.

Firebase Core version

4.13.0 (cloud_firestore 6.8.0; the code is unchanged in 6.9.0 and on main at a646d55)

Flutter Version

3.47.4 (Dart 3.13.3)

Relevant Log Output
FirebaseException: [cloud_firestore/unknown]
_extractReplyValueOrThrow (messages.pigeon.dart:27)
FirebaseFirestoreHostApi.transactionGet (messages.pigeon.dart:1477)
MethodChannelTransaction.get (method_channel_transaction.dart:50)
Transaction.get (transaction.dart:28)
Flutter dependencies

cloud_firestore 6.8.0, cloud_firestore_platform_interface 8.0.6, _flutterfire_internals 1.3.76, firebase_core 4.13.0. Windows 11 (build 26200), release build.

Additional context and comments

Every other error path in the file builds details itself (ParseError, the bundle loader), so this looks like two call sites that were missed rather than a design choice.

Lingua principale
Dart
Stelle
9.3k
Fork
4.1k
Merge medio
1g 14h
PR unite (30g)
39

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di firebase/flutterfire

Tutte le issue di firebase/flutterfire

Issue simili

Altre issue su Dart

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.