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

Desktop RTDB: Repo::HandleTransactionResponse collapses every non-datastale server error (incl. permission_denied) to kErrorUnknownError with an empty message

Aperta
#1,904 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
1-2 giorni
Idoneità per principianti
70/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Tranquilla
Stack tecnologico
cpp
Ambito
databases

Direzione di ricerca

Inizia da database/src/desktop/core/repo.cc, in Repo::HandleTransactionResponse() e RerunTransactionQueue(), quindi confronta il flusso dello stato e del messaggio della risposta in database/src/desktop/connection/persistent_connection.cc. Il lavoro è completato quando gli errori delle transazioni conservano il codice di errore del server mappato e il messaggio, incluso permission_denied, invece di completarsi come kErrorUnknownError con un messaggio vuoto.

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

Descrizione

Environment
  • Firebase C++ SDK 13.9.0 (desktop/Windows; the cited code is unchanged at the 13.11.0 tag)
  • Identified while tracing FlutterFire firebase_database 12.4.6 on Windows; the defect below is independently confirmed from the pinned desktop C++ source.
What happens

When the server rejects a transaction commit (e.g. a security-rules fence returns permission_denied on the wire), the transaction Future<DataSnapshot> completes with:

  • error() = kErrorUnknownError (10) — not kErrorPermissionDenied (8)
  • error_message() = "" (empty)

so callers cannot distinguish "rules denied this commit" from any other failure, and there is no message to log. Plain SetValue() writes on the same path correctly surface kErrorPermissionDenied, which makes the transaction behavior surprising.

Where the information is lost (pinned to 3d7ce2a, the 13.9.0 tag)
  1. The wire layer maps the response status correctly and retains the server message. HandlePutResponse() converts the status and passes the response body to TriggerResponse():
    https://github.com/firebase/firebase-cpp-sdk/blob/3d7ce2a584d0b8daf1374bc2534c6ea71fa7fd6c/database/src/desktop/connection/persistent_connection.cc#L955-L970
    TriggerResponse() stores both values, and the adjacent status map includes permission_deniedkErrorPermissionDenied:
    https://github.com/firebase/firebase-cpp-sdk/blob/3d7ce2a584d0b8daf1374bc2534c6ea71fa7fd6c/database/src/desktop/connection/persistent_connection.cc#L1244-L1281
  2. Repo::HandleTransactionResponse() then discards both fields for every error response other than datastale:
    for (auto& transaction : response->queue()) {
      transaction->status = TransactionData::kStatusNeedsAbort;
      transaction->abort_reason = kErrorUnknownError;
    }
    
    https://github.com/firebase/firebase-cpp-sdk/blob/3d7ce2a584d0b8daf1374bc2534c6ea71fa7fd6c/database/src/desktop/core/repo.cc#L982-L1000
  3. RerunTransactionQueue() finally completes the future with the no-message overload, so error_message() is empty:
    DataSnapshot snapshot(new DataSnapshotInternal(
        database_, node, QuerySpec(transaction->path)));
    transaction->ref_future->CompleteWithResult(transaction->future_handle,
                                                abort_reason, snapshot);
    
    https://github.com/firebase/firebase-cpp-sdk/blob/3d7ce2a584d0b8daf1374bc2534c6ea71fa7fd6c/database/src/desktop/core/repo.cc#L1003-L1138
Expected

abort_reason should carry the mapped response code (8 for permission_denied, etc.) and the completion should pass the response's error message through, matching what the Android SDK reports for the same server rejection.

Impact

Any desktop app implementing fenced/optimistic transactions (rules-enforced epochs, leases, counters) receives an undiagnosable unknown/empty failure for what is actually a well-defined rules denial. Downstream SDK wrappers (e.g. FlutterFire's Windows plugin) inherit the collapsed code, so the loss is user-visible in every binding built on this implementation.

Lingua principale
C++
Stelle
326
Fork
138
Merge medio
2g 16h
PR unite (30g)
3

Guida per i contributori

Apri la guida per i contributori

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/firebase-cpp-sdk

Tutte le issue di firebase/firebase-cpp-sdk

Issue simili

Altre issue su C++

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.