diff --git a/CHANGELOG.md b/CHANGELOG.md index 651aebfdc6..7d8e6d20a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ ### Fixed * ([#????](https://github.com/realm/realm-core/issues/????), since v?.?.?) -* None. +* App subscription callback was getting fired before the user profile was retrieved on login, leading to an empty user profile when using the callback. ([#7889](https://github.com/realm/realm-core/issues/7889), since v14.7.0) ### Breaking changes * The websocket error codes `websocket_client_too_old`, `websocket_client_too_new`, and `websocket_protocol_mismatch` along with their C API constants were removed. These corresponded to errors the legacy C++ server could have sent, but the baas sync server never did. Any platform networking implementations that surfaced these errors can report a `websocket_fatal_error` instead if an unknown error occurs during the websocket handshake. If a client connects that is too old or too new, it will finish the websocket handshake and then receive an in-band sync `ERROR` message that will be handled by the sync error handler. [PR #7917](https://github.com/realm/realm-core/pull/7917) diff --git a/src/realm/object-store/sync/app.cpp b/src/realm/object-store/sync/app.cpp index ebb121d286..2b2a8b0fca 100644 --- a/src/realm/object-store/sync/app.cpp +++ b/src/realm/object-store/sync/app.cpp @@ -835,8 +835,14 @@ void App::log_in_with_credentials(const AppCredentials& credentials, const std:: return completion(nullptr, AppError(ErrorCodes::BadToken, "Could not log in user: received malformed JWT")); } - switch_user(user); - get_profile(user, std::move(completion)); + + get_profile(user, [this, completion = std::move(completion)](const std::shared_ptr& user, + Optional error) { + if (!error) { + switch_user(user); + } + completion(user, error); + }); }, false); } diff --git a/test/object-store/sync/app.cpp b/test/object-store/sync/app.cpp index 680ae6742b..36811ac317 100644 --- a/test/object-store/sync/app.cpp +++ b/test/object-store/sync/app.cpp @@ -4172,6 +4172,17 @@ TEST_CASE("app: jwt login and metadata tests", "[sync][app][user][metadata][func SECTION("jwt happy path") { bool processed = false; + bool logged_in_once = false; + + auto token = app->subscribe([&logged_in_once, &app](auto&) { + REQUIRE(!logged_in_once); + auto user = app->current_user(); + auto metadata = user->user_profile(); + + // Ensure that the JWT metadata fields are available when the callback is fired on login. + CHECK(metadata["name"] == "Foo Bar"); + logged_in_once = true; + }); std::shared_ptr user = log_in(app, AppCredentials::custom(jwt)); @@ -4192,6 +4203,10 @@ TEST_CASE("app: jwt login and metadata tests", "[sync][app][user][metadata][func auto custom_data = *user->custom_data(); CHECK(custom_data["name"] == "Not Foo Bar"); CHECK(metadata["name"] == "Foo Bar"); + + REQUIRE(logged_in_once); + + app->unsubscribe(token); } }