From 1830628db7c5e82077267981ce14cae054801a1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Ali=20Ustao=C4=9Flu?= Date: Fri, 23 Oct 2026 23:21:46 +0200 Subject: [PATCH 1/9] Firebase packages: move to firebase_core 5 and the new FlutterFire majors firebase_core 5.0.0, firebase_auth 7.0.0, firebase_messaging 17.0.0 and firebase_storage 14.0.0 came out on 2026-10-15, and their platform interfaces moved to firebase_core ^5.0.0 together. The weekly upstream job of 2026-10-19 failed on all four Firebase rows. - firebase_auth_watchos, firebase_messaging_watchos and firebase_storage_watchos 0.2.0 depend on firebase_core ^5.0.0 and on the first platform interface for it: firebase_auth_platform_interface ^9.1.1, firebase_messaging_platform_interface ^4.11.0 and firebase_storage_platform_interface ^6.0.8. Only the new majors are supported, because the interface versions that work with firebase_core 5 require it; apps that stay on the old majors keep 0.1.1. - firebase_core_watchos 0.1.2: firebase_core 4.12.1 and later and 5.x all use firebase_core_platform_interface 8.x, which it implements, so its dependencies stay and it works with both. - The READMEs, the examples and tool/upstream_versions.yaml move to firebase_core 5.1.0, firebase_auth 7.0.1, firebase_messaging 17.0.1 and firebase_storage 14.0.1 in one commit, because every one of the four READMEs names firebase_core. - The watch keeps the Firebase Apple SDK 11.x; the move to SDK 13 upstream is for iOS and macOS. No native code changes, and the examples were not rebuilt on the Simulator; the CHANGELOGs, READMEs and porting reports say so. --- packages/firebase_auth_watchos/CHANGELOG.md | 16 +++++++++++++++ .../firebase_auth_watchos/PORTING_REPORT.md | 8 ++++++-- packages/firebase_auth_watchos/README.md | 17 ++++++++++------ .../example/pubspec.yaml | 6 +++--- packages/firebase_auth_watchos/pubspec.yaml | 6 +++--- packages/firebase_core_watchos/CHANGELOG.md | 12 +++++++++++ .../firebase_core_watchos/PORTING_REPORT.md | 8 ++++++-- packages/firebase_core_watchos/README.md | 13 ++++++++---- .../example/pubspec.yaml | 2 +- packages/firebase_core_watchos/pubspec.yaml | 2 +- .../firebase_messaging_watchos/CHANGELOG.md | 17 ++++++++++++++++ .../PORTING_REPORT.md | 9 +++++++-- packages/firebase_messaging_watchos/README.md | 17 ++++++++++------ .../example/pubspec.yaml | 4 ++-- .../firebase_messaging_watchos/pubspec.yaml | 6 +++--- .../firebase_storage_watchos/CHANGELOG.md | 20 +++++++++++++++++++ .../PORTING_REPORT.md | 8 ++++++-- packages/firebase_storage_watchos/README.md | 17 ++++++++++------ .../example/pubspec.yaml | 4 ++-- .../firebase_storage_watchos/pubspec.yaml | 6 +++--- tool/upstream_versions.yaml | 11 +++++----- 21 files changed, 156 insertions(+), 53 deletions(-) diff --git a/packages/firebase_auth_watchos/CHANGELOG.md b/packages/firebase_auth_watchos/CHANGELOG.md index 886686f..8513155 100644 --- a/packages/firebase_auth_watchos/CHANGELOG.md +++ b/packages/firebase_auth_watchos/CHANGELOG.md @@ -1,3 +1,19 @@ +## 0.2.0 + +* **Breaking:** works with `firebase_auth` 7.x, and needs it. The package now + depends on `firebase_core: ^5.0.0` (was `^4.0.0`) and + `firebase_auth_platform_interface: ^9.1.1` (was `^9.0.5`), the first + version of the platform interface for `firebase_core` 5.x. An app that + stays on `firebase_auth` 6.x keeps 0.1.1. +* The watch still links the Firebase Apple SDK 11.x through + `watchos/Package.swift`. The move to SDK 13 in `firebase_auth` 7.0.0 is + for its iOS and macOS code. +* README: the install snippet names `firebase_core: ^5.1.0`, + `firebase_auth: ^7.0.1` and this version. +* Example: `pubspec.yaml` names `firebase_auth: ^7.0.1`, + `firebase_core: ^5.1.0` and `firebase_messaging: ^17.0.1`. No native code + changed, and the example was not rebuilt on the Simulator for this version. + ## 0.1.1 * API docs and comments say "release" for handing native memory back. diff --git a/packages/firebase_auth_watchos/PORTING_REPORT.md b/packages/firebase_auth_watchos/PORTING_REPORT.md index 5959b42..fa75259 100644 --- a/packages/firebase_auth_watchos/PORTING_REPORT.md +++ b/packages/firebase_auth_watchos/PORTING_REPORT.md @@ -3,7 +3,11 @@ Scaffolded by `flutter-watchos plugin port --from-pub firebase_auth --include-example` on 2026-07-17, then hand-finished. -Source: `firebase_auth` 6.5.6 +Source: `firebase_auth` 6.5.6. Since 0.2.0 it implements +`firebase_auth_platform_interface` 9.1.1 and later, for `firebase_auth` 7.x; +read against 7.0.1 and platform interface 9.1.2. The watch still links the +Firebase Apple SDK 11.x (`watchos/Package.resolved` pins 11.15.0), while +`firebase_auth` 7.x builds its iOS code against 13.x. Base platform: ios (Objective-C) Model: **dart:ffi over the Firebase Apple SDK** (`FirebaseAuth`) @@ -14,7 +18,7 @@ Model: **dart:ffi over the Firebase Apple SDK** (`FirebaseAuth`) | Implementation (Dart + FFI + native) | ◐ the watch-viable flows, except the methods the README lists under "Not implemented yet" (reauthentication and linking among them) | | watchOS capability | ◐ email, anonymous and token sign-in are implemented; provider/OAuth, phone, and MFA flows need UI the watch cannot present | | Host unit tests | ✅ 13/13 pass (native FirebaseAuth faked) | -| On-simulator build + link + run | ◐ links the Firebase Apple SDK; the example builds and starts on the watchOS 27.0 Simulator. The smoke test was not run for this version | +| On-simulator build + link + run | ◐ links the Firebase Apple SDK; the example builds and starts on the watchOS 27.0 Simulator (checked with 0.1.1; 0.2.0 changes no native code and was not rebuilt). The smoke test was not run for this version | | Physical watch hardware | ○ not yet verified | | Upstream integration test | ○ none in the firebase_auth pub example (smoke test added) | diff --git a/packages/firebase_auth_watchos/README.md b/packages/firebase_auth_watchos/README.md index 87a0a87..c5cb5ec 100644 --- a/packages/firebase_auth_watchos/README.md +++ b/packages/firebase_auth_watchos/README.md @@ -15,8 +15,10 @@ and the auth-state streams poll the SDK's change notifications. > Firebase support on watchOS is new. > > **What has been checked:** the example app builds and starts on the -> watchOS 27.0 Simulator, and the host unit tests pass. It has not yet been -> run on a physical Apple Watch. +> watchOS 27.0 Simulator, and the host unit tests pass. The Simulator run +> was with 0.1.1 and `firebase_auth` 6.x; 0.2.0 changes no native code, and +> its example has not been rebuilt yet. It has not yet been run on a +> physical Apple Watch. > > Requires `firebase_core_watchos` (the initialization + app registry > foundation) and a `flutter-watchos` CLI with external-SwiftPM-dependency @@ -58,12 +60,15 @@ This is a federated plugin implementation. Apps that already depend on ```yaml dependencies: - firebase_core: ^4.0.0 - firebase_core_watchos: ^0.1.0 - firebase_auth: ^6.0.0 - firebase_auth_watchos: ^0.1.0 + firebase_core: ^5.1.0 + firebase_core_watchos: ^0.1.2 + firebase_auth: ^7.0.1 + firebase_auth_watchos: ^0.2.0 ``` +Version 0.2.0 needs `firebase_auth` 7.x and `firebase_core` 5.x. An app that +stays on `firebase_auth` 6.x uses 0.1.1. + Then use `firebase_auth`'s API exactly as on iOS — the watchOS implementation registers automatically via Flutter's federated plugin runner. diff --git a/packages/firebase_auth_watchos/example/pubspec.yaml b/packages/firebase_auth_watchos/example/pubspec.yaml index ce98ab4..9b11394 100644 --- a/packages/firebase_auth_watchos/example/pubspec.yaml +++ b/packages/firebase_auth_watchos/example/pubspec.yaml @@ -9,15 +9,15 @@ environment: dependencies: flutter: sdk: flutter - firebase_auth: ^6.7.0 + firebase_auth: ^7.0.1 firebase_auth_watchos: path: ../ barcode_widget: "^2.0.4" collection: ^1.16.0 - firebase_core: "^4.12.1" + firebase_core: "^5.1.0" firebase_core_watchos: path: ../../firebase_core_watchos - firebase_messaging: "^16.4.3" + firebase_messaging: "^17.0.1" firebase_messaging_watchos: path: ../../firebase_messaging_watchos flutter_facebook_auth: "^7.1.5" diff --git a/packages/firebase_auth_watchos/pubspec.yaml b/packages/firebase_auth_watchos/pubspec.yaml index a1e26b0..7879859 100644 --- a/packages/firebase_auth_watchos/pubspec.yaml +++ b/packages/firebase_auth_watchos/pubspec.yaml @@ -1,6 +1,6 @@ name: firebase_auth_watchos description: "watchOS implementation of firebase_auth, bridging the Firebase Apple SDK (FirebaseAuth) over dart:ffi for email, anonymous, and token sign-in." -version: 0.1.1 +version: 0.2.0 homepage: https://flutterwatch.dev repository: https://github.com/flutterwatch/plugins issue_tracker: https://github.com/flutterwatch/plugins/issues @@ -24,8 +24,8 @@ environment: dependencies: ffi: ^2.1.0 - firebase_auth_platform_interface: ^9.0.5 - firebase_core: ^4.0.0 + firebase_auth_platform_interface: ^9.1.1 + firebase_core: ^5.0.0 flutter: sdk: flutter diff --git a/packages/firebase_core_watchos/CHANGELOG.md b/packages/firebase_core_watchos/CHANGELOG.md index 3e13d1f..b712bb8 100644 --- a/packages/firebase_core_watchos/CHANGELOG.md +++ b/packages/firebase_core_watchos/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.1.2 + +* Works with `firebase_core` 5.x as well as 4.12.1 and later. They all use + `firebase_core_platform_interface` 8.x, which this package implements, so + its dependencies do not change. The watch still links the Firebase Apple SDK + 11.x through `watchos/Package.swift`; the move to SDK 13 in `firebase_core` + 5.0.0 is for its iOS and macOS code. +* README: the install snippet names `firebase_core: ^5.1.0` and this version, + and says which `firebase_core` versions the package works with. +* Example: `pubspec.yaml` names `firebase_core: ^5.1.0`. No native code + changed, and the example was not rebuilt on the Simulator for this version. + ## 0.1.1 * API docs and comments say "release" for handing native memory back. diff --git a/packages/firebase_core_watchos/PORTING_REPORT.md b/packages/firebase_core_watchos/PORTING_REPORT.md index d74ecaf..6c4883c 100644 --- a/packages/firebase_core_watchos/PORTING_REPORT.md +++ b/packages/firebase_core_watchos/PORTING_REPORT.md @@ -3,7 +3,11 @@ Scaffolded by `flutter-watchos plugin port --from-pub firebase_core --include-example` on 2026-07-17, then hand-finished. -Source: `firebase_core` 4.12.1 +Source: `firebase_core` 4.12.1. Since 0.1.2 also read against +`firebase_core` 5.1.0, which uses the same `firebase_core_platform_interface` +8.x. The watch still links the Firebase Apple SDK 11.x +(`watchos/Package.resolved` pins 11.15.0), while `firebase_core` 5.x builds +its iOS code against 13.x. Base platform: ios (Objective-C) Model: **dart:ffi over the Firebase Apple SDK** (`FirebaseCore`) @@ -14,7 +18,7 @@ Model: **dart:ffi over the Firebase Apple SDK** (`FirebaseCore`) | Implementation (Dart + FFI + native) | ✅ complete | | watchOS capability | ◐ FirebaseCore supports watchOS 8+; SPM manifest allows `.watchOS(.v7)` | | Host unit tests | ✅ 8/8 pass (native FirebaseCore faked) | -| On-simulator build + link + run | ✅ links the Firebase Apple SDK; smoke test passes | +| On-simulator build + link + run | ✅ links the Firebase Apple SDK; smoke test passes (with `firebase_core` 4.x; the example has not been rebuilt with 5.x) | | Physical watch hardware | ○ not yet verified | | Upstream integration test | ○ none in the firebase_core pub example (smoke test added) | diff --git a/packages/firebase_core_watchos/README.md b/packages/firebase_core_watchos/README.md index 6154156..54e76ed 100644 --- a/packages/firebase_core_watchos/README.md +++ b/packages/firebase_core_watchos/README.md @@ -16,8 +16,9 @@ dependency on [`firebase-ios-sdk`](https://github.com/firebase/firebase-ios-sdk) > > **What has been checked:** the example app builds and starts on the > watchOS 27.0 Simulator, the host unit tests pass, and a smoke test that -> initializes the default app and a named app passes there. It has not yet -> been run on a physical Apple Watch. +> initializes the default app and a named app passes there. That was with +> `firebase_core` 4.x; the example has not been rebuilt with 5.x yet. It has +> not yet been run on a physical Apple Watch. > > Requires `flutter-watchos` with external-SwiftPM-dependency linking (the CLI > builds the plugin's SwiftPM package — pulling in `FirebaseCore` — and @@ -51,10 +52,14 @@ This is a federated plugin implementation. Apps that already depend on ```yaml dependencies: - firebase_core: ^4.0.0 - firebase_core_watchos: ^0.1.0 + firebase_core: ^5.1.0 + firebase_core_watchos: ^0.1.2 ``` +`firebase_core` 5.x, and 4.x from 4.12.1, use +`firebase_core_platform_interface` 8.x, which this package implements, so the +package works with either. + Then use `firebase_core`'s API exactly as on iOS — the watchOS implementation registers automatically via Flutter's federated plugin runner. diff --git a/packages/firebase_core_watchos/example/pubspec.yaml b/packages/firebase_core_watchos/example/pubspec.yaml index b7e1ea7..3fe1d3c 100644 --- a/packages/firebase_core_watchos/example/pubspec.yaml +++ b/packages/firebase_core_watchos/example/pubspec.yaml @@ -9,7 +9,7 @@ environment: dependencies: flutter: sdk: flutter - firebase_core: ^4.15.0 + firebase_core: ^5.1.0 firebase_core_watchos: path: ../ diff --git a/packages/firebase_core_watchos/pubspec.yaml b/packages/firebase_core_watchos/pubspec.yaml index 1febfec..31ddb08 100644 --- a/packages/firebase_core_watchos/pubspec.yaml +++ b/packages/firebase_core_watchos/pubspec.yaml @@ -1,6 +1,6 @@ name: firebase_core_watchos description: "watchOS implementation of firebase_core, bridging the Firebase Apple SDK (FirebaseCore) over dart:ffi to configure and read Firebase app instances." -version: 0.1.1 +version: 0.1.2 homepage: https://flutterwatch.dev repository: https://github.com/flutterwatch/plugins issue_tracker: https://github.com/flutterwatch/plugins/issues diff --git a/packages/firebase_messaging_watchos/CHANGELOG.md b/packages/firebase_messaging_watchos/CHANGELOG.md index 24e25b0..bdf6c34 100644 --- a/packages/firebase_messaging_watchos/CHANGELOG.md +++ b/packages/firebase_messaging_watchos/CHANGELOG.md @@ -1,3 +1,20 @@ +## 0.2.0 + +* **Breaking:** works with `firebase_messaging` 17.x, and needs it. The + package now depends on `firebase_core: ^5.0.0` (was `^4.0.0`) and + `firebase_messaging_platform_interface: ^4.11.0` (was `^4.9.0`), the first + version of the platform interface for `firebase_core` 5.x. An app that + stays on `firebase_messaging` 16.x keeps 0.1.1. +* The watch still links the Firebase Apple SDK 11.x through + `watchos/Package.swift`. The move to SDK 13 in `firebase_messaging` 17.0.0 + is for its iOS and macOS code. +* README: the install snippet names `firebase_core: ^5.1.0`, + `firebase_messaging: ^17.0.1` and this version. +* Example: `pubspec.yaml` names `firebase_messaging: ^17.0.1` and + `firebase_core: ^5.1.0`. Its code is unchanged and still calls `getToken` + and `onTokenRefresh`. No native code changed, and the example was not + rebuilt on the Simulator for this version. + ## 0.1.1 * API docs and comments say "release" for handing native memory back. diff --git a/packages/firebase_messaging_watchos/PORTING_REPORT.md b/packages/firebase_messaging_watchos/PORTING_REPORT.md index ee6104f..1a25dcd 100644 --- a/packages/firebase_messaging_watchos/PORTING_REPORT.md +++ b/packages/firebase_messaging_watchos/PORTING_REPORT.md @@ -3,7 +3,12 @@ Scaffolded by `flutter-watchos plugin port --from-pub firebase_messaging --include-example` on 2026-07-18, then hand-finished. -Source: `firebase_messaging` 16.4.3 +Source: `firebase_messaging` 16.4.3. Since 0.2.0 it implements +`firebase_messaging_platform_interface` 4.11.0 and later, for +`firebase_messaging` 17.x; read against 17.0.1 and platform interface 4.11.1. +The watch still links the Firebase Apple SDK 11.x (`watchos/Package.resolved` +pins 11.15.0), while `firebase_messaging` 17.x builds its iOS code against +13.x. Base platform: ios (Objective-C) Model: **dart:ffi over the Firebase Apple SDK** (`FirebaseMessaging`) @@ -14,7 +19,7 @@ Model: **dart:ffi over the Firebase Apple SDK** (`FirebaseMessaging`) | Implementation (Dart + FFI + native) | ✅ complete (background handler is a no-op — see below) | | watchOS capability | ✅ FirebaseMessaging is source-built and watch-capable | | Host unit tests | ✅ 15/15 pass (native FirebaseMessaging faked) | -| On-simulator build + link + run | ◐ links the Firebase Apple SDK; the example builds and starts on the watchOS 27.0 Simulator, where `getToken` fails because the Simulator has no APNs. The smoke test was not run for this version | +| On-simulator build + link + run | ◐ links the Firebase Apple SDK; the example builds and starts on the watchOS 27.0 Simulator, where `getToken` fails because the Simulator has no APNs (checked with 0.1.1; 0.2.0 changes no native code and was not rebuilt). The smoke test was not run for this version | | Physical watch hardware | ○ not yet verified | | Upstream integration test | ○ none in the firebase_messaging pub example (smoke test added) | diff --git a/packages/firebase_messaging_watchos/README.md b/packages/firebase_messaging_watchos/README.md index 41c12db..b10c97d 100644 --- a/packages/firebase_messaging_watchos/README.md +++ b/packages/firebase_messaging_watchos/README.md @@ -16,8 +16,10 @@ platform interface's `onMessage` / `onMessageOpenedApp` streams. > Firebase support on watchOS is new. > > **What has been checked:** the example app builds and starts on the -> watchOS 27.0 Simulator, and the host unit tests pass. It has not yet been -> run on a physical Apple Watch. +> watchOS 27.0 Simulator, and the host unit tests pass. The Simulator run +> was with 0.1.1 and `firebase_messaging` 16.x; 0.2.0 changes no native code, +> and its example has not been rebuilt yet. It has not yet been run on a +> physical Apple Watch. > > Requires `firebase_core_watchos` (the initialization + app registry > foundation) and a `flutter-watchos` CLI with external-SwiftPM-dependency @@ -66,12 +68,15 @@ This is a federated plugin implementation. Apps that already depend on ```yaml dependencies: - firebase_core: ^4.0.0 - firebase_core_watchos: ^0.1.0 - firebase_messaging: ^16.0.0 - firebase_messaging_watchos: ^0.1.0 + firebase_core: ^5.1.0 + firebase_core_watchos: ^0.1.2 + firebase_messaging: ^17.0.1 + firebase_messaging_watchos: ^0.2.0 ``` +Version 0.2.0 needs `firebase_messaging` 17.x and `firebase_core` 5.x. An app +that stays on `firebase_messaging` 16.x uses 0.1.1. + Then use `firebase_messaging`'s API exactly as on iOS — the watchOS implementation registers automatically via Flutter's federated plugin runner. diff --git a/packages/firebase_messaging_watchos/example/pubspec.yaml b/packages/firebase_messaging_watchos/example/pubspec.yaml index 1b94d8f..d2bf0f1 100644 --- a/packages/firebase_messaging_watchos/example/pubspec.yaml +++ b/packages/firebase_messaging_watchos/example/pubspec.yaml @@ -9,10 +9,10 @@ environment: dependencies: flutter: sdk: flutter - firebase_messaging: ^16.7.0 + firebase_messaging: ^17.0.1 firebase_messaging_watchos: path: ../ - firebase_core: "^4.12.1" + firebase_core: "^5.1.0" firebase_core_watchos: path: ../../firebase_core_watchos flutter_local_notifications: "^21.0.0" diff --git a/packages/firebase_messaging_watchos/pubspec.yaml b/packages/firebase_messaging_watchos/pubspec.yaml index 9817912..b520ad0 100644 --- a/packages/firebase_messaging_watchos/pubspec.yaml +++ b/packages/firebase_messaging_watchos/pubspec.yaml @@ -1,6 +1,6 @@ name: firebase_messaging_watchos description: "watchOS implementation of firebase_messaging, bridging the Firebase Apple SDK (FirebaseMessaging) over dart:ffi for tokens, topics, and messages." -version: 0.1.1 +version: 0.2.0 homepage: https://flutterwatch.dev repository: https://github.com/flutterwatch/plugins issue_tracker: https://github.com/flutterwatch/plugins/issues @@ -24,8 +24,8 @@ environment: dependencies: ffi: ^2.1.0 - firebase_core: ^4.0.0 - firebase_messaging_platform_interface: ^4.9.0 + firebase_core: ^5.0.0 + firebase_messaging_platform_interface: ^4.11.0 flutter: sdk: flutter diff --git a/packages/firebase_storage_watchos/CHANGELOG.md b/packages/firebase_storage_watchos/CHANGELOG.md index 68ac0f5..52109c7 100644 --- a/packages/firebase_storage_watchos/CHANGELOG.md +++ b/packages/firebase_storage_watchos/CHANGELOG.md @@ -1,3 +1,23 @@ +## 0.2.0 + +* **Breaking:** works with `firebase_storage` 14.x, and needs it. The package + now depends on `firebase_core: ^5.0.0` (was `^4.0.0`) and + `firebase_storage_platform_interface: ^6.0.8` (was `^6.0.3`), the first + version of the platform interface for `firebase_core` 5.x. An app that stays + on `firebase_storage` 13.x keeps 0.1.1. +* The watch still links the Firebase Apple SDK 11.x through + `watchos/Package.swift`. The move to SDK 13 in `firebase_storage` 14.0.0 is + for its iOS and macOS code. +* The platform interface's one change in 6.0.9, an error snapshot of a + method-channel task that keeps the metadata of the snapshot before it, is + in code this package does not use. A watchOS task snapshot carries metadata + only when an upload succeeds, as before. +* README: the install snippet names `firebase_core: ^5.1.0`, + `firebase_storage: ^14.0.1` and this version. +* Example: `pubspec.yaml` names `firebase_storage: ^14.0.1` and + `firebase_core: ^5.1.0`. No native code changed, and the example was not + rebuilt on the Simulator for this version. + ## 0.1.1 * API docs and comments say "release" for handing native memory back. diff --git a/packages/firebase_storage_watchos/PORTING_REPORT.md b/packages/firebase_storage_watchos/PORTING_REPORT.md index 1cb9499..d1b00c0 100644 --- a/packages/firebase_storage_watchos/PORTING_REPORT.md +++ b/packages/firebase_storage_watchos/PORTING_REPORT.md @@ -3,7 +3,11 @@ Scaffolded by `flutter-watchos plugin port --from-pub firebase_storage --include-example` on 2026-07-17, then hand-finished. -Source: `firebase_storage` 13.4.5 +Source: `firebase_storage` 13.4.5. Since 0.2.0 it implements +`firebase_storage_platform_interface` 6.0.8 and later, for `firebase_storage` +14.x; read against 14.0.1 and platform interface 6.0.9. The watch still links +the Firebase Apple SDK 11.x (`watchos/Package.resolved` pins 11.15.0), while +`firebase_storage` 14.x builds its iOS code against 13.x. Base platform: ios (Swift) Model: **dart:ffi over the Firebase Apple SDK** (`FirebaseStorage`) @@ -14,7 +18,7 @@ Model: **dart:ffi over the Firebase Apple SDK** (`FirebaseStorage`) | Implementation (Dart + FFI + native) | ✅ complete (putBlob is web-only) | | watchOS capability | ✅ FirebaseStorage is source-built and watch-capable | | Host unit tests | ✅ 14/14 pass (native FirebaseStorage faked) | -| On-simulator build + link + run | ◐ links the Firebase Apple SDK; the example builds and starts on the watchOS 27.0 Simulator. The smoke test was not run for this version | +| On-simulator build + link + run | ◐ links the Firebase Apple SDK; the example builds and starts on the watchOS 27.0 Simulator (checked with 0.1.1; 0.2.0 changes no native code and was not rebuilt). The smoke test was not run for this version | | Physical watch hardware | ○ not yet verified | | Upstream integration test | ○ none in the firebase_storage pub example (smoke test added) | diff --git a/packages/firebase_storage_watchos/README.md b/packages/firebase_storage_watchos/README.md index 4e7e736..fa8992b 100644 --- a/packages/firebase_storage_watchos/README.md +++ b/packages/firebase_storage_watchos/README.md @@ -16,8 +16,10 @@ snapshots the Dart side polls. > Firebase support on watchOS is new. > > **What has been checked:** the example app builds and starts on the -> watchOS 27.0 Simulator, and the host unit tests pass. It has not yet been -> run on a physical Apple Watch. +> watchOS 27.0 Simulator, and the host unit tests pass. The Simulator run +> was with 0.1.1 and `firebase_storage` 13.x; 0.2.0 changes no native code, +> and its example has not been rebuilt yet. It has not yet been run on a +> physical Apple Watch. > > Requires `firebase_core_watchos` (the initialization + app registry > foundation) and a `flutter-watchos` CLI with external-SwiftPM-dependency @@ -43,12 +45,15 @@ This is a federated plugin implementation. Apps that already depend on ```yaml dependencies: - firebase_core: ^4.0.0 - firebase_core_watchos: ^0.1.0 - firebase_storage: ^13.0.0 - firebase_storage_watchos: ^0.1.0 + firebase_core: ^5.1.0 + firebase_core_watchos: ^0.1.2 + firebase_storage: ^14.0.1 + firebase_storage_watchos: ^0.2.0 ``` +Version 0.2.0 needs `firebase_storage` 14.x and `firebase_core` 5.x. An app +that stays on `firebase_storage` 13.x uses 0.1.1. + Then use `firebase_storage`'s API exactly as on iOS — the watchOS implementation registers automatically via Flutter's federated plugin runner. diff --git a/packages/firebase_storage_watchos/example/pubspec.yaml b/packages/firebase_storage_watchos/example/pubspec.yaml index a4e60c1..32f9a2b 100644 --- a/packages/firebase_storage_watchos/example/pubspec.yaml +++ b/packages/firebase_storage_watchos/example/pubspec.yaml @@ -9,10 +9,10 @@ environment: dependencies: flutter: sdk: flutter - firebase_storage: ^13.6.0 + firebase_storage: ^14.0.1 firebase_storage_watchos: path: ../ - firebase_core: "^4.12.1" + firebase_core: "^5.1.0" firebase_core_watchos: path: ../../firebase_core_watchos image_picker: "^1.1.2" diff --git a/packages/firebase_storage_watchos/pubspec.yaml b/packages/firebase_storage_watchos/pubspec.yaml index f2f0cad..12876f1 100644 --- a/packages/firebase_storage_watchos/pubspec.yaml +++ b/packages/firebase_storage_watchos/pubspec.yaml @@ -1,6 +1,6 @@ name: firebase_storage_watchos description: "watchOS implementation of firebase_storage, bridging the Firebase Apple SDK (FirebaseStorage) over dart:ffi for uploads, downloads, and metadata." -version: 0.1.1 +version: 0.2.0 homepage: https://flutterwatch.dev repository: https://github.com/flutterwatch/plugins issue_tracker: https://github.com/flutterwatch/plugins/issues @@ -24,8 +24,8 @@ environment: dependencies: ffi: ^2.1.0 - firebase_core: ^4.0.0 - firebase_storage_platform_interface: ^6.0.3 + firebase_core: ^5.0.0 + firebase_storage_platform_interface: ^6.0.8 flutter: sdk: flutter diff --git a/tool/upstream_versions.yaml b/tool/upstream_versions.yaml index 08ec57e..9dde2aa 100644 --- a/tool/upstream_versions.yaml +++ b/tool/upstream_versions.yaml @@ -1,5 +1,6 @@ # The latest version of each upstream package on pub.dev, read from the -# pub.dev API (latest.version) on 2026-09-30. +# pub.dev API (latest.version) on 2026-09-30; the four Firebase upstreams on +# 2026-10-23, when their packages moved to the new majors. # # tool/bin/check_readme_snippets.dart holds every README install snippet to # it: an upstream constraint must be a caret constraint that admits this @@ -11,10 +12,10 @@ upstreams: battery_plus: 7.1.1 connectivity_plus: 7.3.1 device_info_plus: 13.2.0 - firebase_auth: 6.7.0 - firebase_core: 4.15.0 - firebase_messaging: 16.7.0 - firebase_storage: 13.6.0 + firebase_auth: 7.0.1 + firebase_core: 5.1.0 + firebase_messaging: 17.0.1 + firebase_storage: 14.0.1 flutter_secure_storage: 11.2.0 games_services: 5.3.0 geolocator: 14.1.1 From 2bf5bfe25b9e6f269608b048b52dca9facd507e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Ali=20Ustao=C4=9Flu?= Date: Fri, 23 Oct 2026 23:22:14 +0200 Subject: [PATCH 2/9] firebase_messaging_watchos: the FID registration API is not implemented yet firebase_messaging_platform_interface 4.11.0 adds register, unregister, onRegistered and onUnregistered, the Firebase Installation ID registration of firebase_messaging 17. They keep the interface's UnimplementedError on the watch: they need FIRMessaging's registerWithCompletion: and unregisterWithCompletion:, which the Firebase Apple SDK has from 12.16.0, and the watch links 11.x. A test pins that, and the README, the CHANGELOG and the porting report say so. getToken, onTokenRefresh and deleteToken, which 17.x deprecates, keep working. --- packages/firebase_messaging_watchos/CHANGELOG.md | 10 +++++++++- .../firebase_messaging_watchos/PORTING_REPORT.md | 13 ++++++++++--- packages/firebase_messaging_watchos/README.md | 8 ++++++++ .../test/firebase_messaging_watchos_test.dart | 11 +++++++++++ 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/packages/firebase_messaging_watchos/CHANGELOG.md b/packages/firebase_messaging_watchos/CHANGELOG.md index bdf6c34..73cdad6 100644 --- a/packages/firebase_messaging_watchos/CHANGELOG.md +++ b/packages/firebase_messaging_watchos/CHANGELOG.md @@ -8,8 +8,16 @@ * The watch still links the Firebase Apple SDK 11.x through `watchos/Package.swift`. The move to SDK 13 in `firebase_messaging` 17.0.0 is for its iOS and macOS code. +* `register`, `unregister`, `onRegistered` and `onUnregistered`, the Firebase + Installation ID registration that `firebase_messaging` 17.0.0 adds, are not + implemented on watchOS yet and throw `UnimplementedError`. They need + `FIRMessaging`'s `registerWithCompletion:` and `unregisterWithCompletion:`, + which the Firebase Apple SDK has from 12.16.0, and this package links 11.x. + `getToken`, `onTokenRefresh` and `deleteToken`, which 17.0.0 deprecates in + their favour, keep working. A new test checks the four new members. * README: the install snippet names `firebase_core: ^5.1.0`, - `firebase_messaging: ^17.0.1` and this version. + `firebase_messaging: ^17.0.1` and this version, and the implemented surface + lists the members that are not implemented yet. * Example: `pubspec.yaml` names `firebase_messaging: ^17.0.1` and `firebase_core: ^5.1.0`. Its code is unchanged and still calls `getToken` and `onTokenRefresh`. No native code changed, and the example was not diff --git a/packages/firebase_messaging_watchos/PORTING_REPORT.md b/packages/firebase_messaging_watchos/PORTING_REPORT.md index 1a25dcd..24151ee 100644 --- a/packages/firebase_messaging_watchos/PORTING_REPORT.md +++ b/packages/firebase_messaging_watchos/PORTING_REPORT.md @@ -16,9 +16,9 @@ Model: **dart:ffi over the Firebase Apple SDK** (`FirebaseMessaging`) | Aspect | Status | |---|---| -| Implementation (Dart + FFI + native) | ✅ complete (background handler is a no-op — see below) | +| Implementation (Dart + FFI + native) | ◐ complete except the Firebase Installation ID registration of `firebase_messaging` 17 (`register`, `unregister`, `onRegistered`, `onUnregistered`), which is not implemented yet; the background handler is a no-op (see below) | | watchOS capability | ✅ FirebaseMessaging is source-built and watch-capable | -| Host unit tests | ✅ 15/15 pass (native FirebaseMessaging faked) | +| Host unit tests | ✅ 16/16 pass (native FirebaseMessaging faked) | | On-simulator build + link + run | ◐ links the Firebase Apple SDK; the example builds and starts on the watchOS 27.0 Simulator, where `getToken` fails because the Simulator has no APNs (checked with 0.1.1; 0.2.0 changes no native code and was not rebuilt). The smoke test was not run for this version | | Physical watch hardware | ○ not yet verified | | Upstream integration test | ○ none in the firebase_messaging pub example (smoke test added) | @@ -64,6 +64,13 @@ private var flutterAppDelegate isolate to run a Dart handler in. `setDeliveryMetricsExportToBigQuery` is Android/web only. +`register`, `unregister`, `onRegistered` and `onUnregistered`, which +platform interface 4.11.0 adds for `firebase_messaging` 17, keep the +interface's `UnimplementedError`. The Firebase Apple SDK has +`registerWithCompletion:` and `unregisterWithCompletion:` from 12.16.0, and +the watch links 11.x; moving to 12.16 or later needs a Simulator and device +check of its own. + Notification settings are mapped from the watchOS-safe subset of `UNNotificationSettings` (authorization/alert/sound/notificationCenter/critical, plus announcement on watchOS 6+ and timeSensitive on watchOS 8+); badge, @@ -92,7 +99,7 @@ System frameworks/libraries: `Foundation`, `Security`, `WatchKit`, FirebaseMessagingPlatform` with the message pump feeding `onMessage`/`onMessageOpenedApp`, over the FFI bindings. - `test/firebase_messaging_watchos_test.dart` — host tests with the native - backend faked (15/15). + backend faked (16/16). - `example/` — the upstream firebase_messaging example, ported for watchOS (runner refreshed to the host-module model so the app-delegate adaptor is available), plus an added `integration_test/firebase_messaging_smoke_test.dart` diff --git a/packages/firebase_messaging_watchos/README.md b/packages/firebase_messaging_watchos/README.md index b10c97d..04e1e7f 100644 --- a/packages/firebase_messaging_watchos/README.md +++ b/packages/firebase_messaging_watchos/README.md @@ -60,6 +60,14 @@ specified before fetching FCM Token"). isolate to run a handler in — and `setDeliveryMetricsExportToBigQuery` is Android/web only. +**Not implemented yet** (they throw `UnimplementedError`): `register`, +`unregister`, `onRegistered` and `onUnregistered`, the Firebase Installation +ID registration that `firebase_messaging` 17 adds. They need `FIRMessaging`'s +`registerWithCompletion:` and `unregisterWithCompletion:`, which the Firebase +Apple SDK has from 12.16.0, and this package links 11.x. On the watch, use +`getToken` and `onTokenRefresh`, which `firebase_messaging` 17 deprecates but +which keep working here. + ## Usage This is a federated plugin implementation. Apps that already depend on diff --git a/packages/firebase_messaging_watchos/test/firebase_messaging_watchos_test.dart b/packages/firebase_messaging_watchos/test/firebase_messaging_watchos_test.dart index 45ab337..98e4c6b 100644 --- a/packages/firebase_messaging_watchos/test/firebase_messaging_watchos_test.dart +++ b/packages/firebase_messaging_watchos/test/firebase_messaging_watchos_test.dart @@ -275,4 +275,15 @@ void main() { test('isSupported is true on watchOS', () async { expect(await messaging.isSupported(), isTrue); }); + + test('the FID registration API of firebase_messaging 17 is not implemented', + () { + // It needs the Firebase Apple SDK 12.16 or later; the watch links 11.x. + expect(() => messaging.register(), throwsUnimplementedError); + expect(() => messaging.unregister(), throwsUnimplementedError); + expect(() => messaging.onRegistered, throwsUnimplementedError); + expect(() => messaging.onUnregistered, throwsUnimplementedError); + expect(fake.beginRequests, isEmpty); + expect(fake.configureRequests, isEmpty); + }); } From 89de2cfd25f21e8d4f412dc10f7e8c98d6b5e0fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Ali=20Ustao=C4=9Flu?= Date: Fri, 23 Oct 2026 23:22:32 +0200 Subject: [PATCH 3/9] firebase_storage_watchos: test that putString hands on custom metadata firebase_storage 14.0.1 keeps the custom metadata of a data URL upload, and passes the payload to the platform as base64. A new test checks that putString hands that metadata, custom metadata included, to the native upload task. --- .../firebase_storage_watchos/CHANGELOG.md | 3 +++ .../PORTING_REPORT.md | 4 ++-- .../test/firebase_storage_watchos_test.dart | 20 +++++++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/packages/firebase_storage_watchos/CHANGELOG.md b/packages/firebase_storage_watchos/CHANGELOG.md index 52109c7..941265e 100644 --- a/packages/firebase_storage_watchos/CHANGELOG.md +++ b/packages/firebase_storage_watchos/CHANGELOG.md @@ -12,6 +12,9 @@ method-channel task that keeps the metadata of the snapshot before it, is in code this package does not use. A watchOS task snapshot carries metadata only when an upload succeeds, as before. +* `firebase_storage` 14.0.1 keeps the custom metadata of a data URL upload. + `putString` passes the metadata it is given to the native upload, and a new + test checks that the custom metadata arrives. * README: the install snippet names `firebase_core: ^5.1.0`, `firebase_storage: ^14.0.1` and this version. * Example: `pubspec.yaml` names `firebase_storage: ^14.0.1` and diff --git a/packages/firebase_storage_watchos/PORTING_REPORT.md b/packages/firebase_storage_watchos/PORTING_REPORT.md index d1b00c0..0250615 100644 --- a/packages/firebase_storage_watchos/PORTING_REPORT.md +++ b/packages/firebase_storage_watchos/PORTING_REPORT.md @@ -17,7 +17,7 @@ Model: **dart:ffi over the Firebase Apple SDK** (`FirebaseStorage`) |---|---| | Implementation (Dart + FFI + native) | ✅ complete (putBlob is web-only) | | watchOS capability | ✅ FirebaseStorage is source-built and watch-capable | -| Host unit tests | ✅ 14/14 pass (native FirebaseStorage faked) | +| Host unit tests | ✅ 15/15 pass (native FirebaseStorage faked) | | On-simulator build + link + run | ◐ links the Firebase Apple SDK; the example builds and starts on the watchOS 27.0 Simulator (checked with 0.1.1; 0.2.0 changes no native code and was not rebuilt). The smoke test was not run for this version | | Physical watch hardware | ○ not yet verified | | Upstream integration test | ○ none in the firebase_storage pub example (smoke test added) | @@ -64,7 +64,7 @@ and force-loads them into Runner. System frameworks/libraries: `Foundation`, FirebaseStoragePlatform`, `ReferenceWatchos`, `TaskWatchos`, `TaskSnapshotWatchos`, `ListResultWatchos`, over the FFI bindings. - `test/firebase_storage_watchos_test.dart` — host tests with the native - backend faked (14/14). + backend faked (15/15). - `example/` — the upstream firebase_storage example, ported for watchOS, plus an added `integration_test/firebase_storage_smoke_test.dart` (the pub example ships no upstream integration_test). diff --git a/packages/firebase_storage_watchos/test/firebase_storage_watchos_test.dart b/packages/firebase_storage_watchos/test/firebase_storage_watchos_test.dart index c74a885..10a4b3a 100644 --- a/packages/firebase_storage_watchos/test/firebase_storage_watchos_test.dart +++ b/packages/firebase_storage_watchos/test/firebase_storage_watchos_test.dart @@ -191,6 +191,26 @@ void main() { expect(fake.taskRequests.single['data'], base64Encode(utf8.encode('hi'))); }); + test('putString base64 uploads the bytes with the custom metadata', () { + // What firebase_storage 14.0.1 passes for a data URL: the payload as + // base64, and metadata that keeps the caller's custom metadata. + storage.ref('d.txt').putString( + base64Encode(utf8.encode('hi')), + PutStringFormat.base64, + SettableMetadata( + contentType: 'text/plain', + customMetadata: {'owner': 'watch'}, + ), + ); + final Map request = fake.taskRequests.single; + expect(request['kind'], 'putData'); + expect(request['data'], base64Encode(utf8.encode('hi'))); + final Map metadata = + request['metadata']! as Map; + expect(metadata['contentType'], 'text/plain'); + expect(metadata['customMetadata'], {'owner': 'watch'}); + }); + test('task onComplete resolves on the success snapshot', () async { fake.taskSnapshots = >[ { From ec778c1671fd0923b74bd4d72c83235e649ab31a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Ali=20Ustao=C4=9Flu?= Date: Fri, 23 Oct 2026 23:22:51 +0200 Subject: [PATCH 4/9] firebase_auth_watchos: test that updateProfile forwards an explicit null firebase_auth 7.0.1 passes User.updateProfile only the fields it is given, so an omitted field keeps its value on the watch, and a field given as null reaches the platform as a key with a null value. A new test checks that the null is forwarded to the native profile change request. The CHANGELOG says what the Firebase Apple SDK does with it: it clears the field on the local user and sends nothing to the server, as on iOS. --- packages/firebase_auth_watchos/CHANGELOG.md | 6 ++++++ .../firebase_auth_watchos/PORTING_REPORT.md | 4 ++-- .../test/firebase_auth_watchos_test.dart | 17 +++++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/packages/firebase_auth_watchos/CHANGELOG.md b/packages/firebase_auth_watchos/CHANGELOG.md index 8513155..ea409b5 100644 --- a/packages/firebase_auth_watchos/CHANGELOG.md +++ b/packages/firebase_auth_watchos/CHANGELOG.md @@ -8,6 +8,12 @@ * The watch still links the Firebase Apple SDK 11.x through `watchos/Package.swift`. The move to SDK 13 in `firebase_auth` 7.0.0 is for its iOS and macOS code. +* `User.updateProfile`: `firebase_auth` 7.0.1 passes only the fields it is + given, so an omitted field now keeps its value on the watch; this package + already applied only the fields present in the request. A field given as + `null` is forwarded to the SDK's profile change request. The Firebase Apple + SDK then clears it on the local user and does not send it to the server, as + on iOS. A new test checks that the `null` reaches the native layer. * README: the install snippet names `firebase_core: ^5.1.0`, `firebase_auth: ^7.0.1` and this version. * Example: `pubspec.yaml` names `firebase_auth: ^7.0.1`, diff --git a/packages/firebase_auth_watchos/PORTING_REPORT.md b/packages/firebase_auth_watchos/PORTING_REPORT.md index fa75259..867a8cd 100644 --- a/packages/firebase_auth_watchos/PORTING_REPORT.md +++ b/packages/firebase_auth_watchos/PORTING_REPORT.md @@ -17,7 +17,7 @@ Model: **dart:ffi over the Firebase Apple SDK** (`FirebaseAuth`) |---|---| | Implementation (Dart + FFI + native) | ◐ the watch-viable flows, except the methods the README lists under "Not implemented yet" (reauthentication and linking among them) | | watchOS capability | ◐ email, anonymous and token sign-in are implemented; provider/OAuth, phone, and MFA flows need UI the watch cannot present | -| Host unit tests | ✅ 13/13 pass (native FirebaseAuth faked) | +| Host unit tests | ✅ 14/14 pass (native FirebaseAuth faked) | | On-simulator build + link + run | ◐ links the Firebase Apple SDK; the example builds and starts on the watchOS 27.0 Simulator (checked with 0.1.1; 0.2.0 changes no native code and was not rebuilt). The smoke test was not run for this version | | Physical watch hardware | ○ not yet verified | | Upstream integration test | ○ none in the firebase_auth pub example (smoke test added) | @@ -67,7 +67,7 @@ watchOS). FirebaseAuthPlatform`, `UserWatchos extends UserPlatform`, `UserCredentialWatchos`, `MultiFactorWatchos`, over the FFI bindings. - `test/firebase_auth_watchos_test.dart` — host tests with the native backend - faked (13/13). + faked (14/14). - `example/` — the upstream firebase_auth example, ported for watchOS, plus an added `integration_test/firebase_auth_smoke_test.dart` (the pub example ships no upstream integration_test). diff --git a/packages/firebase_auth_watchos/test/firebase_auth_watchos_test.dart b/packages/firebase_auth_watchos/test/firebase_auth_watchos_test.dart index 338ba7d..8b891c3 100644 --- a/packages/firebase_auth_watchos/test/firebase_auth_watchos_test.dart +++ b/packages/firebase_auth_watchos/test/firebase_auth_watchos_test.dart @@ -262,6 +262,23 @@ void main() { expect(request['hasPhotoUrl'], isFalse); }); + test('updateProfile forwards an explicit null', () async { + fake.snapshot = { + 'authGeneration': 1, + 'idTokenGeneration': 1, + 'user': _userMap(), + }; + fake.opResult = {'ok': true}; + // firebase_auth 7.x passes only the fields it is given, so a null it is + // given reaches the platform as a key with a null value. + await auth.currentUser!.updateProfile({'photoURL': null}); + final Map request = fake.beginRequests.single; + expect(request['op'], 'updateProfile'); + expect(request['hasPhotoUrl'], isTrue); + expect(request['photoUrl'], isNull); + expect(request['hasDisplayName'], isFalse); + }); + test('sendPasswordResetEmail completes on ok', () async { fake.opResult = {'ok': true}; await auth.sendPasswordResetEmail('user@example.com'); From 7d7dfad3343f318084c5cdad777c725d30f33a24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Ali=20Ustao=C4=9Flu?= Date: Fri, 23 Oct 2026 23:23:09 +0200 Subject: [PATCH 5/9] firebase_auth_watchos: streams no longer repeat a first or signed-out value The SDK calls each auth listener once when the plugin installs it, on the first native call for an app, and that call bumps the native counter the streams watch. A stream subscribed before any other auth call therefore emitted its first value twice, a user or null. firebase_auth drops a first callback that carries a user, and 7.0.1 (platform interface 9.1.2) also skips a null that follows a null. authStateChanges, idTokenChanges and userChanges now leave out the bump of a counter that was still 0 at their first snapshot, and skip a null when the last value they emitted was null. Tests take each stream through a signed-in start and a signed-out start, with the install call, a sign-in, a sign-out and a repeated signed-out call. The existing stream test now starts after the install call, as the native counters do, and the stream tests cancel their subscriptions in a tear-down. --- packages/firebase_auth_watchos/CHANGELOG.md | 7 ++ .../firebase_auth_watchos/PORTING_REPORT.md | 11 +- .../lib/firebase_auth_watchos.dart | 45 ++++++- .../test/firebase_auth_watchos_test.dart | 118 ++++++++++++++++-- 4 files changed, 165 insertions(+), 16 deletions(-) diff --git a/packages/firebase_auth_watchos/CHANGELOG.md b/packages/firebase_auth_watchos/CHANGELOG.md index ea409b5..c00c55f 100644 --- a/packages/firebase_auth_watchos/CHANGELOG.md +++ b/packages/firebase_auth_watchos/CHANGELOG.md @@ -8,6 +8,13 @@ * The watch still links the Firebase Apple SDK 11.x through `watchos/Package.swift`. The move to SDK 13 in `firebase_auth` 7.0.0 is for its iOS and macOS code. +* `authStateChanges`, `idTokenChanges` and `userChanges` no longer repeat + their first value. The SDK calls each of its listeners once when the plugin + installs them, on the first native call for an app, so with 0.1.1 a stream + subscribed before any other auth call could emit the current user, or null, + a second time. As in `firebase_auth`, the streams now leave that call out. +* The same streams report a signed-out state once, as `firebase_auth` 7.0.1 + does: a null is not emitted when the last value emitted was null too. * `User.updateProfile`: `firebase_auth` 7.0.1 passes only the fields it is given, so an omitted field now keeps its value on the watch; this package already applied only the fields present in the request. A field given as diff --git a/packages/firebase_auth_watchos/PORTING_REPORT.md b/packages/firebase_auth_watchos/PORTING_REPORT.md index 867a8cd..336d83d 100644 --- a/packages/firebase_auth_watchos/PORTING_REPORT.md +++ b/packages/firebase_auth_watchos/PORTING_REPORT.md @@ -17,7 +17,7 @@ Model: **dart:ffi over the Firebase Apple SDK** (`FirebaseAuth`) |---|---| | Implementation (Dart + FFI + native) | ◐ the watch-viable flows, except the methods the README lists under "Not implemented yet" (reauthentication and linking among them) | | watchOS capability | ◐ email, anonymous and token sign-in are implemented; provider/OAuth, phone, and MFA flows need UI the watch cannot present | -| Host unit tests | ✅ 14/14 pass (native FirebaseAuth faked) | +| Host unit tests | ✅ 20/20 pass (native FirebaseAuth faked) | | On-simulator build + link + run | ◐ links the Firebase Apple SDK; the example builds and starts on the watchOS 27.0 Simulator (checked with 0.1.1; 0.2.0 changes no native code and was not rebuilt). The smoke test was not run for this version | | Physical watch hardware | ○ not yet verified | | Upstream integration test | ○ none in the firebase_auth pub example (smoke test added) | @@ -34,7 +34,12 @@ poll-a-generation pattern: the native layer registers the SDK's auth-state/ID-token listeners once per app and bumps counters that `firebase_auth_watchos_current_user` reports alongside the user snapshot; `authStateChanges`/`idTokenChanges`/`userChanges` poll the counters and emit -on change (the poll timer stops when the subscription is cancelled). +on change (the poll timer stops when the subscription is cancelled). The SDK +calls each listener once when it is installed; a counter that is still 0 at a +stream's first snapshot is waiting for that call, so the stream leaves its +first bump out, as `firebase_auth` drops that first callback. As in +`firebase_auth` 7.x, each stream also reports a signed-out state once: a null +is not emitted after a null. Errors carry FlutterFire's string codes: the native layer reads the SDK's `FIRAuthErrorUserInfoNameKey` (`ERROR_WRONG_PASSWORD`) and converts it to the @@ -67,7 +72,7 @@ watchOS). FirebaseAuthPlatform`, `UserWatchos extends UserPlatform`, `UserCredentialWatchos`, `MultiFactorWatchos`, over the FFI bindings. - `test/firebase_auth_watchos_test.dart` — host tests with the native backend - faked (14/14). + faked (20/20). - `example/` — the upstream firebase_auth example, ported for watchOS, plus an added `integration_test/firebase_auth_smoke_test.dart` (the pub example ships no upstream integration_test). diff --git a/packages/firebase_auth_watchos/lib/firebase_auth_watchos.dart b/packages/firebase_auth_watchos/lib/firebase_auth_watchos.dart index e25e375..503464f 100644 --- a/packages/firebase_auth_watchos/lib/firebase_auth_watchos.dart +++ b/packages/firebase_auth_watchos/lib/firebase_auth_watchos.dart @@ -416,20 +416,52 @@ class FirebaseAuthWatchos extends FirebaseAuthPlatform { // A fresh stream per call, matching FlutterFire semantics: emits the // current user immediately, then again whenever the watched generation // moves. The generation is bumped natively by the SDK's listeners. + // + // The native side installs the listeners on the first native call for an + // app, and the SDK then calls each one once, asynchronously, with the + // current user: a bump that reports no change. A counter that is still 0 + // at this stream's first snapshot is waiting for that call, so its first + // bump is left out. firebase_auth drops the same first callback when it + // carries a user. + // + // As in firebase_auth 7.x, a signed-out state is reported once: a null is + // skipped when the last value emitted, the first one included, was null + // too. Stream _watch(int Function(_AuthSnapshot) generationOf) { late StreamController controller; int? lastGeneration; + bool signedOut = false; + bool? authInstallCallPending; + bool? idTokenInstallCallPending; void onPoll( _AuthSnapshot? snapshot, Object? error, StackTrace? stackTrace) { if (error != null) { controller.addError(error, stackTrace!); return; } - final int generation = generationOf(snapshot!); - if (generation != lastGeneration) { - lastGeneration = generation; - controller.add(snapshot.user); + final _AuthSnapshot current = snapshot!; + final bool authPending = + authInstallCallPending ??= current.authGeneration == 0; + final bool idTokenPending = + idTokenInstallCallPending ??= current.idTokenGeneration == 0; + final int generation = generationOf(_AuthSnapshot( + authGeneration: + _withoutInstallCall(current.authGeneration, authPending), + idTokenGeneration: + _withoutInstallCall(current.idTokenGeneration, idTokenPending), + userMutations: current.userMutations, + user: current.user, + )); + if (generation == lastGeneration) { + return; + } + lastGeneration = generation; + final UserPlatform? user = current.user; + if (user == null && signedOut) { + return; } + signedOut = user == null; + controller.add(user); } controller = StreamController( @@ -450,6 +482,11 @@ class FirebaseAuthWatchos extends FirebaseAuthPlatform { return controller.stream; } + // A native listener counter without the bump of the listener's install + // call, when that call was still to come at a stream's first snapshot. + static int _withoutInstallCall(int generation, bool installCallPending) => + installCallPending && generation > 0 ? generation - 1 : generation; + /// Starts a native operation and polls until its result arrives. /// Throws [FirebaseAuthException] on an in-band error. Future> _awaitOp(Map request) async { diff --git a/packages/firebase_auth_watchos/test/firebase_auth_watchos_test.dart b/packages/firebase_auth_watchos/test/firebase_auth_watchos_test.dart index 8b891c3..08a1031 100644 --- a/packages/firebase_auth_watchos/test/firebase_auth_watchos_test.dart +++ b/packages/firebase_auth_watchos/test/firebase_auth_watchos_test.dart @@ -110,6 +110,79 @@ class _FakeBindings extends FirebaseAuthWatchosBindings { } } +// Listens to the stream [changes] returns and collects the uids it emits. The +// subscription is cancelled when the test ends, passed or failed. +List _listenUids(Stream Function() changes) { + final List seen = []; + final StreamSubscription subscription = + changes().listen((UserPlatform? user) => seen.add(user?.uid)); + addTearDown(subscription.cancel); + return seen; +} + +// Serves a native snapshot with both listener counters at [generation], as +// when the SDK's two listeners report the same event, and lets the change +// streams poll it. +Future _report( + _FakeBindings fake, + int generation, + Map? user, +) { + fake.snapshot = { + 'authGeneration': generation, + 'idTokenGeneration': generation, + 'user': user, + }; + return Future.delayed(const Duration(milliseconds: 30)); +} + +// A signed-out start, the call the SDK makes to each listener it installs, a +// sign-in, a sign-out and a second call for the same signed-out state: each +// signed-out state is reported once, as firebase_auth 7.x does. +Future _expectSignedOutReportedOnce( + _FakeBindings fake, + Stream Function() changes, +) async { + final List seen = _listenUids(changes); + await Future.delayed(const Duration(milliseconds: 20)); + expect(seen, [null]); + + await _report(fake, 1, null); + expect(seen, [null]); + + await _report(fake, 2, _userMap()); + expect(seen, [null, 'uid-1']); + + await _report(fake, 3, null); + expect(seen, [null, 'uid-1', null]); + + await _report(fake, 4, null); + expect(seen, [null, 'uid-1', null]); +} + +// A signed-in start, then the call the SDK makes to each listener it +// installs: the user is emitted once, as firebase_auth does. A sign-out after +// that call is reported. +Future _expectInstallCallLeftOut( + _FakeBindings fake, + Stream Function() changes, +) async { + fake.snapshot = { + 'authGeneration': 0, + 'idTokenGeneration': 0, + 'user': _userMap(), + }; + final List seen = _listenUids(changes); + await Future.delayed(const Duration(milliseconds: 20)); + expect(seen, ['uid-1']); + + await _report(fake, 1, _userMap()); + expect(seen, ['uid-1']); + + await _report(fake, 2, null); + expect(seen, ['uid-1', null]); +} + void main() { late _FakeBindings fake; late FirebaseAuthWatchos auth; @@ -288,16 +361,20 @@ void main() { test('authStateChanges emits the current user, then on generation change', () async { - final List seen = []; - final Stream stream = auth.authStateChanges(); - final StreamSubscription sub = - stream.listen((UserPlatform? user) => seen.add(user?.uid)); + // The listeners were installed, and the SDK made its first call to each, + // before this subscription. + fake.snapshot = { + 'authGeneration': 1, + 'idTokenGeneration': 1, + 'user': null, + }; + final List seen = _listenUids(auth.authStateChanges); await Future.delayed(const Duration(milliseconds: 20)); expect(seen, [null]); fake.snapshot = { - 'authGeneration': 1, - 'idTokenGeneration': 1, + 'authGeneration': 2, + 'idTokenGeneration': 2, 'user': _userMap(), }; await Future.delayed(const Duration(milliseconds: 30)); @@ -305,13 +382,36 @@ void main() { // An idToken-only change must not re-emit on authStateChanges. fake.snapshot = { - 'authGeneration': 1, - 'idTokenGeneration': 2, + 'authGeneration': 2, + 'idTokenGeneration': 3, 'user': _userMap(), }; await Future.delayed(const Duration(milliseconds: 30)); expect(seen, [null, 'uid-1']); - await sub.cancel(); + }); + + test('authStateChanges reports a signed-out state once', () async { + await _expectSignedOutReportedOnce(fake, auth.authStateChanges); + }); + + test('idTokenChanges reports a signed-out state once', () async { + await _expectSignedOutReportedOnce(fake, auth.idTokenChanges); + }); + + test('userChanges reports a signed-out state once', () async { + await _expectSignedOutReportedOnce(fake, auth.userChanges); + }); + + test('authStateChanges leaves out the listener install call', () async { + await _expectInstallCallLeftOut(fake, auth.authStateChanges); + }); + + test('idTokenChanges leaves out the listener install call', () async { + await _expectInstallCallLeftOut(fake, auth.idTokenChanges); + }); + + test('userChanges leaves out the listener install call', () async { + await _expectInstallCallLeftOut(fake, auth.userChanges); }); test('delegateFor returns one instance per app', () { From 62164c30843f77b0d0f7be35d5ec852c32e04ed9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Ali=20Ustao=C4=9Flu?= Date: Fri, 23 Oct 2026 23:23:28 +0200 Subject: [PATCH 6/9] firebase_auth_watchos README: ActionCodeSettings are not passed on sendPasswordResetEmail, sendEmailVerification and verifyBeforeUpdateEmail send their email without the ActionCodeSettings they are given. The README now lists that under "Not implemented yet". --- packages/firebase_auth_watchos/CHANGELOG.md | 4 +++- packages/firebase_auth_watchos/README.md | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/firebase_auth_watchos/CHANGELOG.md b/packages/firebase_auth_watchos/CHANGELOG.md index c00c55f..9a9bd0d 100644 --- a/packages/firebase_auth_watchos/CHANGELOG.md +++ b/packages/firebase_auth_watchos/CHANGELOG.md @@ -22,7 +22,9 @@ SDK then clears it on the local user and does not send it to the server, as on iOS. A new test checks that the `null` reaches the native layer. * README: the install snippet names `firebase_core: ^5.1.0`, - `firebase_auth: ^7.0.1` and this version. + `firebase_auth: ^7.0.1` and this version. "Not implemented yet" now lists + the `ActionCodeSettings` that `sendPasswordResetEmail`, + `sendEmailVerification` and `verifyBeforeUpdateEmail` do not pass on. * Example: `pubspec.yaml` names `firebase_auth: ^7.0.1`, `firebase_core: ^5.1.0` and `firebase_messaging: ^17.0.1`. No native code changed, and the example was not rebuilt on the Simulator for this version. diff --git a/packages/firebase_auth_watchos/README.md b/packages/firebase_auth_watchos/README.md index c5cb5ec..3012a5c 100644 --- a/packages/firebase_auth_watchos/README.md +++ b/packages/firebase_auth_watchos/README.md @@ -50,7 +50,10 @@ enrollment. These throw `UnimplementedError` or report `unimplemented`. `User.reauthenticateWithCredential`, `User.linkWithCredential`, `User.unlink`, `sendSignInLinkToEmail`, `checkActionCode` and `setSettings`. Without reauthentication, Firebase rejects `updatePassword` and `delete` with -`requires-recent-login` once the last sign-in is too old. +`requires-recent-login` once the last sign-in is too old. Passing on +`ActionCodeSettings` is not implemented yet either: `sendPasswordResetEmail`, +`sendEmailVerification` and `verifyBeforeUpdateEmail` send their email without +the settings they are given. ## Usage From 0481c19a4417b139d7a8cee2c4f1a26df013f518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Ali=20Ustao=C4=9Flu?= Date: Fri, 23 Oct 2026 23:38:10 +0200 Subject: [PATCH 7/9] firebase_auth_watchos: report a sign-out that the listener install call carries The SDK's install call reports the user it has when the call runs, not when the listener was installed, and the auth-state listener reports a uid only once. A sign-out after a stream's first snapshot and before that call runs therefore bumps the auth counter once, and the previous commit left that bump out, so authStateChanges kept the signed-in user. A move of a stream's generation that is only the install calls is now left out when it reports the value the stream last emitted, and emitted when the user changed before the call ran. Other moves are emitted as before, except a null after a null. New tests take each stream through a signed-in start and a sign-out that the install call carries, then the sign-out's own report. --- packages/firebase_auth_watchos/CHANGELOG.md | 4 +- .../firebase_auth_watchos/PORTING_REPORT.md | 15 ++++---- .../lib/firebase_auth_watchos.dart | 37 +++++++++++++------ .../test/firebase_auth_watchos_test.dart | 36 ++++++++++++++++++ 4 files changed, 72 insertions(+), 20 deletions(-) diff --git a/packages/firebase_auth_watchos/CHANGELOG.md b/packages/firebase_auth_watchos/CHANGELOG.md index 9a9bd0d..d1c71e8 100644 --- a/packages/firebase_auth_watchos/CHANGELOG.md +++ b/packages/firebase_auth_watchos/CHANGELOG.md @@ -12,7 +12,9 @@ their first value. The SDK calls each of its listeners once when the plugin installs them, on the first native call for an app, so with 0.1.1 a stream subscribed before any other auth call could emit the current user, or null, - a second time. As in `firebase_auth`, the streams now leave that call out. + a second time. The streams now leave that call out when it reports the + value they last emitted, and emit it when the user changed before it ran: + for `authStateChanges` it can be the only report of such a sign-out. * The same streams report a signed-out state once, as `firebase_auth` 7.0.1 does: a null is not emitted when the last value emitted was null too. * `User.updateProfile`: `firebase_auth` 7.0.1 passes only the fields it is diff --git a/packages/firebase_auth_watchos/PORTING_REPORT.md b/packages/firebase_auth_watchos/PORTING_REPORT.md index 336d83d..c54fa4e 100644 --- a/packages/firebase_auth_watchos/PORTING_REPORT.md +++ b/packages/firebase_auth_watchos/PORTING_REPORT.md @@ -17,7 +17,7 @@ Model: **dart:ffi over the Firebase Apple SDK** (`FirebaseAuth`) |---|---| | Implementation (Dart + FFI + native) | ◐ the watch-viable flows, except the methods the README lists under "Not implemented yet" (reauthentication and linking among them) | | watchOS capability | ◐ email, anonymous and token sign-in are implemented; provider/OAuth, phone, and MFA flows need UI the watch cannot present | -| Host unit tests | ✅ 20/20 pass (native FirebaseAuth faked) | +| Host unit tests | ✅ 23/23 pass (native FirebaseAuth faked) | | On-simulator build + link + run | ◐ links the Firebase Apple SDK; the example builds and starts on the watchOS 27.0 Simulator (checked with 0.1.1; 0.2.0 changes no native code and was not rebuilt). The smoke test was not run for this version | | Physical watch hardware | ○ not yet verified | | Upstream integration test | ○ none in the firebase_auth pub example (smoke test added) | @@ -35,11 +35,12 @@ auth-state/ID-token listeners once per app and bumps counters that `firebase_auth_watchos_current_user` reports alongside the user snapshot; `authStateChanges`/`idTokenChanges`/`userChanges` poll the counters and emit on change (the poll timer stops when the subscription is cancelled). The SDK -calls each listener once when it is installed; a counter that is still 0 at a -stream's first snapshot is waiting for that call, so the stream leaves its -first bump out, as `firebase_auth` drops that first callback. As in -`firebase_auth` 7.x, each stream also reports a signed-out state once: a null -is not emitted after a null. +calls each listener once when it is installed, with the user it has when the +call runs. A counter that is still 0 at a stream's first snapshot is waiting +for that call, and a move that is only that call is left out when it reports +the value the stream last emitted; when the user changed before the call ran, +it is emitted. As in `firebase_auth` 7.x, each stream also reports a +signed-out state once: a null is not emitted after a null. Errors carry FlutterFire's string codes: the native layer reads the SDK's `FIRAuthErrorUserInfoNameKey` (`ERROR_WRONG_PASSWORD`) and converts it to the @@ -72,7 +73,7 @@ watchOS). FirebaseAuthPlatform`, `UserWatchos extends UserPlatform`, `UserCredentialWatchos`, `MultiFactorWatchos`, over the FFI bindings. - `test/firebase_auth_watchos_test.dart` — host tests with the native backend - faked (20/20). + faked (23/23). - `example/` — the upstream firebase_auth example, ported for watchOS, plus an added `integration_test/firebase_auth_smoke_test.dart` (the pub example ships no upstream integration_test). diff --git a/packages/firebase_auth_watchos/lib/firebase_auth_watchos.dart b/packages/firebase_auth_watchos/lib/firebase_auth_watchos.dart index 503464f..aa8d041 100644 --- a/packages/firebase_auth_watchos/lib/firebase_auth_watchos.dart +++ b/packages/firebase_auth_watchos/lib/firebase_auth_watchos.dart @@ -418,11 +418,14 @@ class FirebaseAuthWatchos extends FirebaseAuthPlatform { // moves. The generation is bumped natively by the SDK's listeners. // // The native side installs the listeners on the first native call for an - // app, and the SDK then calls each one once, asynchronously, with the - // current user: a bump that reports no change. A counter that is still 0 - // at this stream's first snapshot is waiting for that call, so its first - // bump is left out. firebase_auth drops the same first callback when it - // carries a user. + // app, and the SDK then calls each one once, asynchronously, with the user + // it has when the call runs. A counter that is still 0 at this stream's + // first snapshot is waiting for that call. When a move of the generation + // is that call alone, it is left out if it reports the user the stream + // last emitted, and emitted if the user changed before the call ran: the + // auth-state listener reports a uid only once, so that call may be the + // only report of a sign-out. firebase_auth drops a first callback that + // carries a user and forwards one that carries none. // // As in firebase_auth 7.x, a signed-out state is reported once: a null is // skipped when the last value emitted, the first one included, was null @@ -430,7 +433,9 @@ class FirebaseAuthWatchos extends FirebaseAuthPlatform { Stream _watch(int Function(_AuthSnapshot) generationOf) { late StreamController controller; int? lastGeneration; - bool signedOut = false; + int? lastSettledGeneration; + bool emitted = false; + String? lastUid; bool? authInstallCallPending; bool? idTokenInstallCallPending; void onPoll( @@ -444,7 +449,13 @@ class FirebaseAuthWatchos extends FirebaseAuthPlatform { authInstallCallPending ??= current.authGeneration == 0; final bool idTokenPending = idTokenInstallCallPending ??= current.idTokenGeneration == 0; - final int generation = generationOf(_AuthSnapshot( + final int generation = generationOf(current); + if (generation == lastGeneration) { + return; + } + // The generation without the install calls: when it did not move, the + // install calls are all that happened. + final int settledGeneration = generationOf(_AuthSnapshot( authGeneration: _withoutInstallCall(current.authGeneration, authPending), idTokenGeneration: @@ -452,15 +463,17 @@ class FirebaseAuthWatchos extends FirebaseAuthPlatform { userMutations: current.userMutations, user: current.user, )); - if (generation == lastGeneration) { - return; - } + final bool installCallsOnly = settledGeneration == lastSettledGeneration; lastGeneration = generation; + lastSettledGeneration = settledGeneration; final UserPlatform? user = current.user; - if (user == null && signedOut) { + if (emitted && + user?.uid == lastUid && + (user == null || installCallsOnly)) { return; } - signedOut = user == null; + emitted = true; + lastUid = user?.uid; controller.add(user); } diff --git a/packages/firebase_auth_watchos/test/firebase_auth_watchos_test.dart b/packages/firebase_auth_watchos/test/firebase_auth_watchos_test.dart index 08a1031..2117e51 100644 --- a/packages/firebase_auth_watchos/test/firebase_auth_watchos_test.dart +++ b/packages/firebase_auth_watchos/test/firebase_auth_watchos_test.dart @@ -183,6 +183,29 @@ Future _expectInstallCallLeftOut( expect(seen, ['uid-1', null]); } +// A signed-in start and a sign-out before the SDK's install call runs: that +// call reports the signed-out state, and for authStateChanges it is the only +// report, so it is emitted. The sign-out's own report that follows is not. +Future _expectSignOutInInstallCallReported( + _FakeBindings fake, + Stream Function() changes, +) async { + fake.snapshot = { + 'authGeneration': 0, + 'idTokenGeneration': 0, + 'user': _userMap(), + }; + final List seen = _listenUids(changes); + await Future.delayed(const Duration(milliseconds: 20)); + expect(seen, ['uid-1']); + + await _report(fake, 1, null); + expect(seen, ['uid-1', null]); + + await _report(fake, 2, null); + expect(seen, ['uid-1', null]); +} + void main() { late _FakeBindings fake; late FirebaseAuthWatchos auth; @@ -414,6 +437,19 @@ void main() { await _expectInstallCallLeftOut(fake, auth.userChanges); }); + test('authStateChanges reports a sign-out the install call carries', + () async { + await _expectSignOutInInstallCallReported(fake, auth.authStateChanges); + }); + + test('idTokenChanges reports a sign-out the install call carries', () async { + await _expectSignOutInInstallCallReported(fake, auth.idTokenChanges); + }); + + test('userChanges reports a sign-out the install call carries', () async { + await _expectSignOutInInstallCallReported(fake, auth.userChanges); + }); + test('delegateFor returns one instance per app', () { FirebaseAuthWatchos.registerWith(); final TestFirebaseApp app = TestFirebaseApp('secondary'); From d06b4b4ddcf6adcaa1325be27dd98059877dfcab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Ali=20Ustao=C4=9Flu?= Date: Fri, 23 Oct 2026 23:38:19 +0200 Subject: [PATCH 8/9] Firebase docs: no SDK 13 claim for upstream, and ActionCodeSettings apart FlutterFire's new majors move Swift Package Manager builds to Firebase Apple SDK 13 but keep CocoaPods builds on 12.19.x, so the CHANGELOGs and porting reports now say that the newer SDK upstream uses on iOS and macOS does not apply to the watch, without naming 13. The auth README listed the ActionCodeSettings that three calls do not pass on under "Not implemented yet (they throw UnimplementedError)", but those calls do not throw; that is now a paragraph of its own. --- packages/firebase_auth_watchos/CHANGELOG.md | 10 +++++----- packages/firebase_auth_watchos/PORTING_REPORT.md | 4 ++-- packages/firebase_auth_watchos/README.md | 9 +++++---- packages/firebase_core_watchos/CHANGELOG.md | 4 ++-- packages/firebase_core_watchos/PORTING_REPORT.md | 10 +++++----- packages/firebase_messaging_watchos/CHANGELOG.md | 4 ++-- packages/firebase_messaging_watchos/PORTING_REPORT.md | 4 ++-- packages/firebase_storage_watchos/CHANGELOG.md | 4 ++-- packages/firebase_storage_watchos/PORTING_REPORT.md | 5 +++-- 9 files changed, 28 insertions(+), 26 deletions(-) diff --git a/packages/firebase_auth_watchos/CHANGELOG.md b/packages/firebase_auth_watchos/CHANGELOG.md index d1c71e8..8d32469 100644 --- a/packages/firebase_auth_watchos/CHANGELOG.md +++ b/packages/firebase_auth_watchos/CHANGELOG.md @@ -6,8 +6,8 @@ version of the platform interface for `firebase_core` 5.x. An app that stays on `firebase_auth` 6.x keeps 0.1.1. * The watch still links the Firebase Apple SDK 11.x through - `watchos/Package.swift`. The move to SDK 13 in `firebase_auth` 7.0.0 is - for its iOS and macOS code. + `watchos/Package.swift`. The newer SDK that `firebase_auth` 7.x uses on iOS + and macOS does not apply to it. * `authStateChanges`, `idTokenChanges` and `userChanges` no longer repeat their first value. The SDK calls each of its listeners once when the plugin installs them, on the first native call for an app, so with 0.1.1 a stream @@ -24,9 +24,9 @@ SDK then clears it on the local user and does not send it to the server, as on iOS. A new test checks that the `null` reaches the native layer. * README: the install snippet names `firebase_core: ^5.1.0`, - `firebase_auth: ^7.0.1` and this version. "Not implemented yet" now lists - the `ActionCodeSettings` that `sendPasswordResetEmail`, - `sendEmailVerification` and `verifyBeforeUpdateEmail` do not pass on. + `firebase_auth: ^7.0.1` and this version, and says that + `sendPasswordResetEmail`, `sendEmailVerification` and + `verifyBeforeUpdateEmail` do not pass on their `ActionCodeSettings` yet. * Example: `pubspec.yaml` names `firebase_auth: ^7.0.1`, `firebase_core: ^5.1.0` and `firebase_messaging: ^17.0.1`. No native code changed, and the example was not rebuilt on the Simulator for this version. diff --git a/packages/firebase_auth_watchos/PORTING_REPORT.md b/packages/firebase_auth_watchos/PORTING_REPORT.md index c54fa4e..9596c7c 100644 --- a/packages/firebase_auth_watchos/PORTING_REPORT.md +++ b/packages/firebase_auth_watchos/PORTING_REPORT.md @@ -6,8 +6,8 @@ Scaffolded by `flutter-watchos plugin port --from-pub firebase_auth Source: `firebase_auth` 6.5.6. Since 0.2.0 it implements `firebase_auth_platform_interface` 9.1.1 and later, for `firebase_auth` 7.x; read against 7.0.1 and platform interface 9.1.2. The watch still links the -Firebase Apple SDK 11.x (`watchos/Package.resolved` pins 11.15.0), while -`firebase_auth` 7.x builds its iOS code against 13.x. +Firebase Apple SDK 11.x (`watchos/Package.resolved` pins 11.15.0); the newer +SDK that `firebase_auth` 7.x uses on iOS and macOS does not apply to it. Base platform: ios (Objective-C) Model: **dart:ffi over the Firebase Apple SDK** (`FirebaseAuth`) diff --git a/packages/firebase_auth_watchos/README.md b/packages/firebase_auth_watchos/README.md index 3012a5c..3200c50 100644 --- a/packages/firebase_auth_watchos/README.md +++ b/packages/firebase_auth_watchos/README.md @@ -50,10 +50,11 @@ enrollment. These throw `UnimplementedError` or report `unimplemented`. `User.reauthenticateWithCredential`, `User.linkWithCredential`, `User.unlink`, `sendSignInLinkToEmail`, `checkActionCode` and `setSettings`. Without reauthentication, Firebase rejects `updatePassword` and `delete` with -`requires-recent-login` once the last sign-in is too old. Passing on -`ActionCodeSettings` is not implemented yet either: `sendPasswordResetEmail`, -`sendEmailVerification` and `verifyBeforeUpdateEmail` send their email without -the settings they are given. +`requires-recent-login` once the last sign-in is too old. + +`sendPasswordResetEmail`, `sendEmailVerification` and +`verifyBeforeUpdateEmail` send their email without the `ActionCodeSettings` +they are given: passing those on is not implemented yet. ## Usage diff --git a/packages/firebase_core_watchos/CHANGELOG.md b/packages/firebase_core_watchos/CHANGELOG.md index b712bb8..3d46c82 100644 --- a/packages/firebase_core_watchos/CHANGELOG.md +++ b/packages/firebase_core_watchos/CHANGELOG.md @@ -3,8 +3,8 @@ * Works with `firebase_core` 5.x as well as 4.12.1 and later. They all use `firebase_core_platform_interface` 8.x, which this package implements, so its dependencies do not change. The watch still links the Firebase Apple SDK - 11.x through `watchos/Package.swift`; the move to SDK 13 in `firebase_core` - 5.0.0 is for its iOS and macOS code. + 11.x through `watchos/Package.swift`; the newer SDK that `firebase_core` 5.x + uses on iOS and macOS does not apply to it. * README: the install snippet names `firebase_core: ^5.1.0` and this version, and says which `firebase_core` versions the package works with. * Example: `pubspec.yaml` names `firebase_core: ^5.1.0`. No native code diff --git a/packages/firebase_core_watchos/PORTING_REPORT.md b/packages/firebase_core_watchos/PORTING_REPORT.md index 6c4883c..0d4ac77 100644 --- a/packages/firebase_core_watchos/PORTING_REPORT.md +++ b/packages/firebase_core_watchos/PORTING_REPORT.md @@ -3,11 +3,11 @@ Scaffolded by `flutter-watchos plugin port --from-pub firebase_core --include-example` on 2026-07-17, then hand-finished. -Source: `firebase_core` 4.12.1. Since 0.1.2 also read against -`firebase_core` 5.1.0, which uses the same `firebase_core_platform_interface` -8.x. The watch still links the Firebase Apple SDK 11.x -(`watchos/Package.resolved` pins 11.15.0), while `firebase_core` 5.x builds -its iOS code against 13.x. +Source: `firebase_core` 4.12.1. Since 0.1.2 also read against `firebase_core` +5.1.0, which uses the same `firebase_core_platform_interface` 8.x. The watch +still links the Firebase Apple SDK 11.x (`watchos/Package.resolved` pins +11.15.0); the newer SDK that `firebase_core` 5.x uses on iOS and macOS does +not apply to it. Base platform: ios (Objective-C) Model: **dart:ffi over the Firebase Apple SDK** (`FirebaseCore`) diff --git a/packages/firebase_messaging_watchos/CHANGELOG.md b/packages/firebase_messaging_watchos/CHANGELOG.md index 73cdad6..36b8b95 100644 --- a/packages/firebase_messaging_watchos/CHANGELOG.md +++ b/packages/firebase_messaging_watchos/CHANGELOG.md @@ -6,8 +6,8 @@ version of the platform interface for `firebase_core` 5.x. An app that stays on `firebase_messaging` 16.x keeps 0.1.1. * The watch still links the Firebase Apple SDK 11.x through - `watchos/Package.swift`. The move to SDK 13 in `firebase_messaging` 17.0.0 - is for its iOS and macOS code. + `watchos/Package.swift`. The newer SDK that `firebase_messaging` 17.x uses + on iOS and macOS does not apply to it. * `register`, `unregister`, `onRegistered` and `onUnregistered`, the Firebase Installation ID registration that `firebase_messaging` 17.0.0 adds, are not implemented on watchOS yet and throw `UnimplementedError`. They need diff --git a/packages/firebase_messaging_watchos/PORTING_REPORT.md b/packages/firebase_messaging_watchos/PORTING_REPORT.md index 24151ee..9f0744d 100644 --- a/packages/firebase_messaging_watchos/PORTING_REPORT.md +++ b/packages/firebase_messaging_watchos/PORTING_REPORT.md @@ -7,8 +7,8 @@ Source: `firebase_messaging` 16.4.3. Since 0.2.0 it implements `firebase_messaging_platform_interface` 4.11.0 and later, for `firebase_messaging` 17.x; read against 17.0.1 and platform interface 4.11.1. The watch still links the Firebase Apple SDK 11.x (`watchos/Package.resolved` -pins 11.15.0), while `firebase_messaging` 17.x builds its iOS code against -13.x. +pins 11.15.0); the newer SDK that `firebase_messaging` 17.x uses on iOS and +macOS does not apply to it. Base platform: ios (Objective-C) Model: **dart:ffi over the Firebase Apple SDK** (`FirebaseMessaging`) diff --git a/packages/firebase_storage_watchos/CHANGELOG.md b/packages/firebase_storage_watchos/CHANGELOG.md index 941265e..3b9b054 100644 --- a/packages/firebase_storage_watchos/CHANGELOG.md +++ b/packages/firebase_storage_watchos/CHANGELOG.md @@ -6,8 +6,8 @@ version of the platform interface for `firebase_core` 5.x. An app that stays on `firebase_storage` 13.x keeps 0.1.1. * The watch still links the Firebase Apple SDK 11.x through - `watchos/Package.swift`. The move to SDK 13 in `firebase_storage` 14.0.0 is - for its iOS and macOS code. + `watchos/Package.swift`. The newer SDK that `firebase_storage` 14.x uses on + iOS and macOS does not apply to it. * The platform interface's one change in 6.0.9, an error snapshot of a method-channel task that keeps the metadata of the snapshot before it, is in code this package does not use. A watchOS task snapshot carries metadata diff --git a/packages/firebase_storage_watchos/PORTING_REPORT.md b/packages/firebase_storage_watchos/PORTING_REPORT.md index 0250615..d274dda 100644 --- a/packages/firebase_storage_watchos/PORTING_REPORT.md +++ b/packages/firebase_storage_watchos/PORTING_REPORT.md @@ -6,8 +6,9 @@ Scaffolded by `flutter-watchos plugin port --from-pub firebase_storage Source: `firebase_storage` 13.4.5. Since 0.2.0 it implements `firebase_storage_platform_interface` 6.0.8 and later, for `firebase_storage` 14.x; read against 14.0.1 and platform interface 6.0.9. The watch still links -the Firebase Apple SDK 11.x (`watchos/Package.resolved` pins 11.15.0), while -`firebase_storage` 14.x builds its iOS code against 13.x. +the Firebase Apple SDK 11.x (`watchos/Package.resolved` pins 11.15.0); the +newer SDK that `firebase_storage` 14.x uses on iOS and macOS does not apply to +it. Base platform: ios (Swift) Model: **dart:ffi over the Firebase Apple SDK** (`FirebaseStorage`) From 847d6fe1c71c4284c24ddc954402572158672541 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Ali=20Ustao=C4=9Flu?= Date: Fri, 23 Oct 2026 23:45:04 +0200 Subject: [PATCH 9/9] firebase_auth_watchos: name the repeat that is left, and model the sign-out post The CHANGELOG said the streams no longer repeat their first value. That holds for the listener install call. idTokenChanges and userChanges can still emit a signed-in user twice when the SDK restores or signs in that user while the plugin installs its listeners, because the SDK's own change notification then bumps the ID-token counter too. The CHANGELOG now says so, and the porting report lists it as a known difference with the native change that would remove it. In the test of a sign-out carried by the install call, the sign-out's own report now bumps only the ID-token counter, as the uid-filtered auth-state listener does not fire again; it also checks that such a move does not re-emit on authStateChanges. --- packages/firebase_auth_watchos/CHANGELOG.md | 15 +++++++++------ packages/firebase_auth_watchos/PORTING_REPORT.md | 8 +++++++- .../test/firebase_auth_watchos_test.dart | 11 +++++++++-- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/packages/firebase_auth_watchos/CHANGELOG.md b/packages/firebase_auth_watchos/CHANGELOG.md index 8d32469..c483df5 100644 --- a/packages/firebase_auth_watchos/CHANGELOG.md +++ b/packages/firebase_auth_watchos/CHANGELOG.md @@ -9,12 +9,15 @@ `watchos/Package.swift`. The newer SDK that `firebase_auth` 7.x uses on iOS and macOS does not apply to it. * `authStateChanges`, `idTokenChanges` and `userChanges` no longer repeat - their first value. The SDK calls each of its listeners once when the plugin - installs them, on the first native call for an app, so with 0.1.1 a stream - subscribed before any other auth call could emit the current user, or null, - a second time. The streams now leave that call out when it reports the - value they last emitted, and emit it when the user changed before it ran: - for `authStateChanges` it can be the only report of such a sign-out. + their first value for the call the SDK makes to each listener when the + plugin installs it, on the first native call for an app. With 0.1.1 a + stream subscribed before any other auth call could emit the current user, + or null, a second time. The streams now leave that call out when it reports + the value they last emitted, and emit it when the user changed before it + ran: for `authStateChanges` it can be the only report of such a sign-out. + `idTokenChanges` and `userChanges` can still emit a signed-in user twice + when the SDK restores or signs in that user while the plugin installs its + listeners; `firebase_auth` usually emits it once there. * The same streams report a signed-out state once, as `firebase_auth` 7.0.1 does: a null is not emitted when the last value emitted was null too. * `User.updateProfile`: `firebase_auth` 7.0.1 passes only the fields it is diff --git a/packages/firebase_auth_watchos/PORTING_REPORT.md b/packages/firebase_auth_watchos/PORTING_REPORT.md index 9596c7c..e356cdb 100644 --- a/packages/firebase_auth_watchos/PORTING_REPORT.md +++ b/packages/firebase_auth_watchos/PORTING_REPORT.md @@ -40,7 +40,13 @@ call runs. A counter that is still 0 at a stream's first snapshot is waiting for that call, and a move that is only that call is left out when it reports the value the stream last emitted; when the user changed before the call ran, it is emitted. As in `firebase_auth` 7.x, each stream also reports a -signed-out state once: a null is not emitted after a null. +signed-out state once: a null is not emitted after a null. A known +difference: `idTokenChanges` and `userChanges` can still emit a signed-in +user twice when the SDK restores or signs in that user while the listeners +are being installed, because its own change notification then bumps the +ID-token counter as well. Installing the listeners from a later main-queue +block, after reading `currentUser`, would remove it; that is a native change +still to make and check on the Simulator. Errors carry FlutterFire's string codes: the native layer reads the SDK's `FIRAuthErrorUserInfoNameKey` (`ERROR_WRONG_PASSWORD`) and converts it to the diff --git a/packages/firebase_auth_watchos/test/firebase_auth_watchos_test.dart b/packages/firebase_auth_watchos/test/firebase_auth_watchos_test.dart index 2117e51..27aa62d 100644 --- a/packages/firebase_auth_watchos/test/firebase_auth_watchos_test.dart +++ b/packages/firebase_auth_watchos/test/firebase_auth_watchos_test.dart @@ -185,7 +185,9 @@ Future _expectInstallCallLeftOut( // A signed-in start and a sign-out before the SDK's install call runs: that // call reports the signed-out state, and for authStateChanges it is the only -// report, so it is emitted. The sign-out's own report that follows is not. +// report, so it is emitted. The sign-out's own report that follows bumps +// only the ID-token counter, as the auth-state listener reports a uid once, +// and is not emitted again. Future _expectSignOutInInstallCallReported( _FakeBindings fake, Stream Function() changes, @@ -202,7 +204,12 @@ Future _expectSignOutInInstallCallReported( await _report(fake, 1, null); expect(seen, ['uid-1', null]); - await _report(fake, 2, null); + fake.snapshot = { + 'authGeneration': 1, + 'idTokenGeneration': 2, + 'user': null, + }; + await Future.delayed(const Duration(milliseconds: 30)); expect(seen, ['uid-1', null]); }