Visitar URL original
fix(firestore,core,windows): per-engine BinaryMessenger, Firestore/Au… · firebase/flutterfire@5dfd289 · GitHub
Skip to content

Commit 5dfd289

Browse files
authored
fix(firestore,core,windows): per-engine BinaryMessenger, Firestore/Auth link order, Profile builds (#18516)
Three separate Windows bugs: - cloud_firestore stored its BinaryMessenger in a class-level static and reassigned it on every RegisterWithRegistrar, so in an app hosting several Flutter engines (e.g. desktop_multi_window) the last engine to register owned the messenger process-wide. Snapshot listeners opened from any other engine were delivered to the wrong isolate and silently never fired, and once that engine was destroyed the dangling pointer crashed the next snapshot call. The messenger is now a per-instance member threaded through the event channel builders. - cloud_firestore listed firebase_auth before firebase_firestore. MSVC resolves static libraries in link-line order and the SDK declares no dependency between the two imported targets, so apps using Firestore without Firebase Auth failed with an unresolved firebase::g_auth_initializer. - firebase_core patched IMPORTED_LOCATION only for DEBUG and RELEASE. The SDK never sets IMPORTED_CONFIGURATIONS, so every other configuration fell back to the Debug libraries. Flutter maps Profile's flags onto Release, so a Profile build compiled against the release CRT and linked debug-CRT libraries, failing on __imp__CrtDbgReport / __imp__invalid_parameter. Profile, RelWithDebInfo and MinSizeRel now resolve to the release libraries, and the windows e2e job gained a Profile build so it cannot regress.
1 parent 8d0afcd commit 5dfd289

5 files changed

Lines changed: 38 additions & 20 deletions

File tree

‎.github/workflows/windows.yaml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ jobs:
6363
npm install -g firebase-tools
6464
- name: "Build Windows (Release)"
6565
run: cd tests && flutter build windows --release
66+
- name: "Build Windows (Profile)"
67+
run: cd tests && flutter build windows --profile
6668
- name: Start Firebase Emulator and run tests
6769
run: cd ./.github/workflows/scripts && firebase emulators:exec --project flutterfire-e2e-tests "cd ../../../tests && flutter test .\integration_test\e2e_test.dart -d windows --verbose"
6870

‎packages/cloud_firestore/cloud_firestore/windows/CMakeLists.txt‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,12 @@ target_compile_definitions(${PLUGIN_NAME} PRIVATE -DINTERNAL_EXPERIMENTAL=1)
6666
# Source include directories and library dependencies. Add any plugin-specific
6767
# dependencies here.
6868
set(MSVC_RUNTIME_MODE MD)
69-
set(firebase_libs firebase_core_plugin firebase_auth firebase_firestore)
69+
# firebase_auth must come after firebase_firestore: the Firestore desktop
70+
# credentials provider pulls symbols out of firebase_auth (e.g.
71+
# `firebase::g_auth_initializer`), the Firebase C++ SDK does not declare that
72+
# dependency between its imported targets, and MSVC resolves static libraries
73+
# in the order they appear on the link line.
74+
set(firebase_libs firebase_core_plugin firebase_firestore firebase_auth)
7075
set(ADDITIONAL_LIBS advapi32 ws2_32 crypt32 rpcrt4 ole32 shell32 Bcrypt.lib DbgHelp.lib)
7176
target_link_libraries(${PLUGIN_NAME} PRIVATE "${firebase_libs}" "${ADDITIONAL_LIBS}")
7277

‎packages/cloud_firestore/cloud_firestore/windows/cloud_firestore_plugin.cpp‎

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ void CloudFirestorePlugin::RegisterWithRegistrar(
255255

256256
auto plugin = std::make_unique<CloudFirestorePlugin>();
257257

258-
messenger_ = registrar->messenger();
258+
plugin->messenger_ = registrar->messenger();
259259

260260
FirebaseFirestoreHostApi::SetUp(registrar->messenger(), plugin.get());
261261

@@ -327,9 +327,6 @@ firebase::firestore::FieldValue CloudFirestorePlugin::ConvertToFieldValue(
327327
}
328328
}
329329

330-
flutter::BinaryMessenger*
331-
cloud_firestore_windows::CloudFirestorePlugin::messenger_ = nullptr;
332-
333330
std::map<std::string,
334331
std::unique_ptr<flutter::EventChannel<flutter::EncodableValue>>>
335332
event_channels_;
@@ -343,12 +340,12 @@ std::map<std::string, std::unique_ptr<firebase::firestore::Firestore>>
343340
cloud_firestore_windows::CloudFirestorePlugin::firestoreInstances_;
344341

345342
std::string RegisterEventChannelWithUUID(
346-
std::string prefix, std::string uuid,
343+
flutter::BinaryMessenger* messenger, std::string prefix, std::string uuid,
347344
std::unique_ptr<flutter::StreamHandler<flutter::EncodableValue>> handler) {
348345
std::string channelName = prefix + uuid;
349346
event_channels_[channelName] =
350347
std::make_unique<flutter::EventChannel<flutter::EncodableValue>>(
351-
CloudFirestorePlugin::messenger_, channelName,
348+
messenger, channelName,
352349
&flutter::StandardMethodCodec::GetInstance(
353350
&FirebaseFirestoreHostApiCodecSerializer::GetInstance()));
354351

@@ -361,7 +358,7 @@ std::string RegisterEventChannelWithUUID(
361358
}
362359

363360
std::string RegisterEventChannel(
364-
std::string prefix,
361+
flutter::BinaryMessenger* messenger, std::string prefix,
365362
std::unique_ptr<flutter::StreamHandler<flutter::EncodableValue>> handler) {
366363
UUID uuid;
367364
UuidCreate(&uuid);
@@ -371,7 +368,7 @@ std::string RegisterEventChannel(
371368
std::string channelName = prefix + str;
372369
event_channels_[channelName] =
373370
std::make_unique<flutter::EventChannel<flutter::EncodableValue>>(
374-
CloudFirestorePlugin::messenger_, channelName,
371+
messenger, channelName,
375372
&flutter::StandardMethodCodec::GetInstance(
376373
&FirebaseFirestoreHostApiCodecSerializer::GetInstance()));
377374
stream_handlers_[channelName] = std::move(handler);
@@ -831,7 +828,8 @@ void CloudFirestorePlugin::LoadBundle(
831828
std::make_unique<LoadBundleStreamHandler>(firestore, bundleConverted);
832829

833830
std::string channelName = RegisterEventChannel(
834-
"plugins.flutter.io/firebase_firestore/loadBundle/", std::move(handler));
831+
messenger_, "plugins.flutter.io/firebase_firestore/loadBundle/",
832+
std::move(handler));
835833

836834
result(channelName);
837835
}
@@ -1029,7 +1027,7 @@ void CloudFirestorePlugin::SnapshotsInSyncSetup(
10291027
std::string snapshotInSyncId(str);
10301028

10311029
std::string channelName = RegisterEventChannelWithUUID(
1032-
"plugins.flutter.io/firebase_firestore/snapshotsInSync/",
1030+
messenger_, "plugins.flutter.io/firebase_firestore/snapshotsInSync/",
10331031
snapshotInSyncId, std::move(handler));
10341032
result(snapshotInSyncId);
10351033
}
@@ -1202,8 +1200,8 @@ void CloudFirestorePlugin::TransactionCreate(
12021200

12031201
// Register the event channel.
12041202
std::string channelName = RegisterEventChannelWithUUID(
1205-
"plugins.flutter.io/firebase_firestore/transaction/", transactionId,
1206-
std::move(handler));
1203+
messenger_, "plugins.flutter.io/firebase_firestore/transaction/",
1204+
transactionId, std::move(handler));
12071205

12081206
// Return the result (assumed to be transaction ID in this example).
12091207
result(transactionId);
@@ -1864,9 +1862,9 @@ void CloudFirestorePlugin::QuerySnapshot(
18641862
GetServerTimestampBehaviorFromPigeon(
18651863
options.server_timestamp_behavior()));
18661864

1867-
std::string channelName =
1868-
RegisterEventChannel("plugins.flutter.io/firebase_firestore/query/",
1869-
std::move(query_snapshot_handler));
1865+
std::string channelName = RegisterEventChannel(
1866+
messenger_, "plugins.flutter.io/firebase_firestore/query/",
1867+
std::move(query_snapshot_handler));
18701868

18711869
result(channelName);
18721870
}
@@ -1962,9 +1960,9 @@ void CloudFirestorePlugin::DocumentReferenceSnapshot(
19621960
GetServerTimestampBehaviorFromPigeon(
19631961
*parameters.server_timestamp_behavior()));
19641962

1965-
std::string channelName =
1966-
RegisterEventChannel("plugins.flutter.io/firebase_firestore/document/",
1967-
std::move(document_snapshot_handler));
1963+
std::string channelName = RegisterEventChannel(
1964+
messenger_, "plugins.flutter.io/firebase_firestore/document/",
1965+
std::move(document_snapshot_handler));
19681966
result(channelName);
19691967
}
19701968

‎packages/cloud_firestore/cloud_firestore/windows/cloud_firestore_plugin.h‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,12 @@ class CloudFirestorePlugin : public flutter::Plugin,
176176
std::function<void(ErrorOr<InternalPipelineSnapshot> reply)> result)
177177
override;
178178

179-
static flutter::BinaryMessenger* messenger_;
179+
// Per-registration messenger. A Windows app can host several Flutter engines
180+
// in the same process (e.g. via `desktop_multi_window`), and each one
181+
// registers the plugin with its own registrar. Keeping this per instance
182+
// means every channel is built on the messenger of the engine that asked for
183+
// it, instead of whichever engine registered last.
184+
flutter::BinaryMessenger* messenger_ = nullptr;
180185
static std::map<
181186
std::string,
182187
std::unique_ptr<flutter::EventChannel<flutter::EncodableValue>>>

‎packages/firebase_core/firebase_core/windows/CMakeLists.txt‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,17 @@ set(FIREBASE_RELEASE_PATH_LIBS firebase_app firebase_auth firebase_remote_config
126126
foreach(firebase_lib IN ITEMS ${FIREBASE_RELEASE_PATH_LIBS})
127127
get_target_property(firebase_lib_path ${firebase_lib} IMPORTED_LOCATION)
128128
string(REPLACE "Debug" "Release" firebase_lib_release_path ${firebase_lib_path})
129+
# Flutter builds Windows apps in Debug, Profile or Release. Profile uses the
130+
# release CRT (Flutter maps its compiler/linker flags onto Release), so it
131+
# must pick the release libraries too - without an explicit mapping CMake
132+
# falls back to plain IMPORTED_LOCATION, which the SDK points at Debug, and
133+
# linking fails with unresolved __imp__CrtDbgReport / __imp__invalid_parameter.
129134
set_target_properties(${firebase_lib} PROPERTIES
130135
IMPORTED_LOCATION_DEBUG "${firebase_lib_path}"
131136
IMPORTED_LOCATION_RELEASE "${firebase_lib_release_path}"
137+
IMPORTED_LOCATION_PROFILE "${firebase_lib_release_path}"
138+
IMPORTED_LOCATION_RELWITHDEBINFO "${firebase_lib_release_path}"
139+
IMPORTED_LOCATION_MINSIZEREL "${firebase_lib_release_path}"
132140
)
133141
endforeach()
134142

0 commit comments

Comments
 (0)