[cloud_firestore][Windows] Transaction read and commit errors lose the Firestore error code (reported as `unknown`)
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
- Ambito
- database, desktop-dev
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
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:
-
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.
-
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 intoPlatformException.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
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di firebase/flutterfire
-
[cloud_firestore]: a snapshots() listener cancelled while it registers is never removed nativelyApertaNeeds Attention platform: android platform: ios platform: macos plugin: cloud_firestore reproduced type: bug
Difficoltà 3/5 1-2 giorni Idoneità per principianti 72/100
firebase/flutterfire#18724 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
blocked: customer-response platform: web plugin: cloud_firestore type: bug
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
firebase/flutterfire#18700 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Needs Attention platform: ios plugin: messaging reproduced type: bug
Difficoltà 3/5 1-2 giorni Idoneità per principianti 74/100
firebase/flutterfire#18699 · 4 commenti · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno
-
blocked: flutter platform: windows plugin: storage reproduced type: bug
Difficoltà 5/5 Più di una settimana Idoneità per principianti 25/100
firebase/flutterfire#18664 · 3 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
[core] Decouple platform_interface from Flutter for pure-Dart webForse già presa @Lyokone l’ha presa 13 giorni fa. ApertaNeeds Attention platform: all platform: web plugin: core type: enhancement
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
firebase/flutterfire#18645 · 2 commenti · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di firebase/flutterfire
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
immich-app/immich#31955 ·
I maintainer di solito rispondono entro 1 giorno
-
bug triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
fluttercommunity/plus_plugins#3994 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
-
Smart charging: USB charger re-assert is starved during BLE scans, so the tablet never dischargesApertabug ready-for-agent
Difficoltà 2/5 1-3 ore Idoneità per principianti 86/100
decentespresso/decaid#931 ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 92/100
flame-engine/flame#4067 ·
I maintainer di solito rispondono entro 1 giorno