Desktop RTDB: Repo::HandleTransactionResponse collapses every non-datastale server error (incl. permission_denied) to kErrorUnknownError with an empty message
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 70/100
Research direction
Start in database/src/desktop/core/repo.cc at Repo::HandleTransactionResponse() and RerunTransactionQueue(), then compare the response status and message flow in database/src/desktop/connection/persistent_connection.cc. Done means transaction failures preserve the mapped server error code and message, including permission_denied, instead of completing as kErrorUnknownError with an empty message.
Written by the indexing model from the issue text.
Description
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_database12.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) — notkErrorPermissionDenied(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)
- The wire layer maps the response status correctly and retains the server message.
HandlePutResponse()converts the status and passes the response body toTriggerResponse():
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 includespermission_denied→kErrorPermissionDenied:
https://github.com/firebase/firebase-cpp-sdk/blob/3d7ce2a584d0b8daf1374bc2534c6ea71fa7fd6c/database/src/desktop/connection/persistent_connection.cc#L1244-L1281 Repo::HandleTransactionResponse()then discards both fields for every error response other thandatastale:
https://github.com/firebase/firebase-cpp-sdk/blob/3d7ce2a584d0b8daf1374bc2534c6ea71fa7fd6c/database/src/desktop/core/repo.cc#L982-L1000for (auto& transaction : response->queue()) { transaction->status = TransactionData::kStatusNeedsAbort; transaction->abort_reason = kErrorUnknownError; }RerunTransactionQueue()finally completes the future with the no-message overload, soerror_message()is empty:
https://github.com/firebase/firebase-cpp-sdk/blob/3d7ce2a584d0b8daf1374bc2534c6ea71fa7fd6c/database/src/desktop/core/repo.cc#L1003-L1138DataSnapshot snapshot(new DataSnapshotInternal( database_, node, QuerySpec(transaction->path))); transaction->ref_future->CompleteWithResult(transaction->future_handle, abort_reason, snapshot);
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.
- Dominant language
- C++
- Stars
- 326
- Forks
- 138
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 6
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from firebase/firebase-cpp-sdk
-
new type: question
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
firebase/firebase-cpp-sdk#1926 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
firebase/firebase-cpp-sdk#1905 · 2 comments ·
-
api: firestore
Difficulty 5/5 Over a week Newbie friendliness 35/100
firebase/firebase-cpp-sdk#1920 · 3 comments ·
-
new type: question
Difficulty 4/5 3-5 days Newbie friendliness 45/100
firebase/firebase-cpp-sdk#1892 · 1 comment ·
-
nightly-testing
Difficulty 4/5 3-5 days Newbie friendliness 25/100
firebase/firebase-cpp-sdk#1859 ·
All issues in firebase/firebase-cpp-sdk
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
drogonframework/drogon#2605 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
ArthurSonzogni/FTXUI#1363 ·
-
Difficulty 1/5 Under an hour Newbie friendliness 94/100
MiSTer-devel/Main_MiSTer#1325 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100