diff --git a/.github/workflows/android.yaml b/.github/workflows/android.yaml index 9f1704ef4b56..48f49f6aa003 100644 --- a/.github/workflows/android.yaml +++ b/.github/workflows/android.yaml @@ -33,7 +33,7 @@ jobs: ['tests', 'packages/cloud_firestore/cloud_firestore/example'] steps: - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b + - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af name: Install Node.js 20 with: node-version: '20' diff --git a/.github/workflows/e2e_tests_fdc.yaml b/.github/workflows/e2e_tests_fdc.yaml index 808999ae4695..75da448493dd 100644 --- a/.github/workflows/e2e_tests_fdc.yaml +++ b/.github/workflows/e2e_tests_fdc.yaml @@ -29,7 +29,7 @@ jobs: fail-fast: false steps: - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 + - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af name: Install Node.js 20 with: node-version: '20' @@ -48,7 +48,7 @@ jobs: channel: 'stable' cache: true - name: Setup PostgreSQL for Linux/macOS/Windows - uses: ikalnytskyi/action-setup-postgres@v6 + uses: ikalnytskyi/action-setup-postgres@v7 - uses: bluefireteam/melos-action@c7dcb921b23cc520cace360b95d02b37bf09cdaa with: run-bootstrap: false @@ -96,7 +96,7 @@ jobs: fail-fast: false steps: - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 + - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af name: Install Node.js 20 with: node-version: '20' @@ -105,7 +105,7 @@ jobs: distribution: 'temurin' java-version: '17' - name: Setup PostgreSQL for Linux/macOS/Windows - uses: ikalnytskyi/action-setup-postgres@v6 + uses: ikalnytskyi/action-setup-postgres@v7 - uses: hendrikmuhs/ccache-action@c92f40bee50034e84c763e33b317c77adaa81c92 name: Xcode Compile Cache with: @@ -176,7 +176,7 @@ jobs: fail-fast: false steps: - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 + - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af name: Install Node.js 20 with: node-version: '20' @@ -185,7 +185,7 @@ jobs: distribution: 'temurin' java-version: '17' - name: Setup PostgreSQL for Linux/macOS/Windows - uses: ikalnytskyi/action-setup-postgres@v6 + uses: ikalnytskyi/action-setup-postgres@v7 - uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1 with: channel: 'stable' diff --git a/.github/workflows/ios.yaml b/.github/workflows/ios.yaml index d73caa57659f..ff1e64e57522 100644 --- a/.github/workflows/ios.yaml +++ b/.github/workflows/ios.yaml @@ -33,7 +33,7 @@ jobs: ['tests', 'packages/cloud_firestore/cloud_firestore/example'] steps: - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b + - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af name: Install Node.js 20 with: node-version: '20' diff --git a/.github/workflows/macos.yaml b/.github/workflows/macos.yaml index 6d054386627c..2b7a01792818 100644 --- a/.github/workflows/macos.yaml +++ b/.github/workflows/macos.yaml @@ -33,7 +33,7 @@ jobs: ['tests', 'packages/cloud_firestore/cloud_firestore/example'] steps: - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b + - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af name: Install Node.js 20 with: node-version: '20' diff --git a/.github/workflows/ossf-scorecard.yml b/.github/workflows/ossf-scorecard.yml index ce615e942768..7e1c26934dae 100644 --- a/.github/workflows/ossf-scorecard.yml +++ b/.github/workflows/ossf-scorecard.yml @@ -59,7 +59,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: SARIF file path: results.sarif diff --git a/.github/workflows/web.yaml b/.github/workflows/web.yaml index b12cb8079f28..135be0335d35 100644 --- a/.github/workflows/web.yaml +++ b/.github/workflows/web.yaml @@ -33,7 +33,7 @@ jobs: ['tests', 'packages/cloud_firestore/cloud_firestore/example'] steps: - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b + - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af name: Install Node.js 20 with: node-version: '20' @@ -85,7 +85,7 @@ jobs: timeout-minutes: 15 steps: - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b + - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af name: Install Node.js 20 with: node-version: '20' @@ -142,7 +142,7 @@ jobs: ['tests', 'packages/cloud_firestore/cloud_firestore/example'] steps: - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b + - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af name: Install Node.js 20 with: node-version: '20' diff --git a/.github/workflows/windows.yaml b/.github/workflows/windows.yaml index 2cacdde63bd2..7cca3809b9de 100644 --- a/.github/workflows/windows.yaml +++ b/.github/workflows/windows.yaml @@ -32,7 +32,7 @@ jobs: with: distribution: 'temurin' java-version: '17' - - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b + - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af name: Install Node.js 20 with: node-version: "20" @@ -64,7 +64,7 @@ jobs: with: distribution: 'temurin' java-version: '17' - - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b + - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af name: Install Node.js 20 with: node-version: "20" diff --git a/packages/cloud_firestore/cloud_firestore/android/src/main/java/io/flutter/plugins/firebase/firestore/FlutterFirebaseFirestoreMessageCodec.java b/packages/cloud_firestore/cloud_firestore/android/src/main/java/io/flutter/plugins/firebase/firestore/FlutterFirebaseFirestoreMessageCodec.java index c7ceb6b36f7c..0e0247915b7c 100644 --- a/packages/cloud_firestore/cloud_firestore/android/src/main/java/io/flutter/plugins/firebase/firestore/FlutterFirebaseFirestoreMessageCodec.java +++ b/packages/cloud_firestore/cloud_firestore/android/src/main/java/io/flutter/plugins/firebase/firestore/FlutterFirebaseFirestoreMessageCodec.java @@ -290,11 +290,11 @@ private FirebaseFirestore readFirestoreInstance(ByteBuffer buffer) { String databaseURL = (String) readValue(buffer); FirebaseFirestoreSettings settings = (FirebaseFirestoreSettings) readValue(buffer); synchronized (FlutterFirebaseFirestorePlugin.firestoreInstanceCache) { - if (FlutterFirebaseFirestorePlugin.getFirestoreInstanceByNameAndDatabaseUrl( - appName, databaseURL) - != null) { - return FlutterFirebaseFirestorePlugin.getFirestoreInstanceByNameAndDatabaseUrl( - appName, databaseURL); + FirebaseFirestore cachedFirestoreInstance = + FlutterFirebaseFirestorePlugin.getFirestoreInstanceByNameAndDatabaseUrl( + appName, databaseURL); + if (cachedFirestoreInstance != null) { + return cachedFirestoreInstance; } FirebaseApp app = FirebaseApp.getInstance(appName); diff --git a/packages/cloud_firestore/cloud_firestore/android/src/main/java/io/flutter/plugins/firebase/firestore/FlutterFirebaseFirestorePlugin.java b/packages/cloud_firestore/cloud_firestore/android/src/main/java/io/flutter/plugins/firebase/firestore/FlutterFirebaseFirestorePlugin.java index 0804d9939438..35e4697f7128 100644 --- a/packages/cloud_firestore/cloud_firestore/android/src/main/java/io/flutter/plugins/firebase/firestore/FlutterFirebaseFirestorePlugin.java +++ b/packages/cloud_firestore/cloud_firestore/android/src/main/java/io/flutter/plugins/firebase/firestore/FlutterFirebaseFirestorePlugin.java @@ -309,11 +309,11 @@ static FirebaseFirestoreSettings getSettingsFromPigeon( public static FirebaseFirestore getFirestoreFromPigeon( GeneratedAndroidFirebaseFirestore.FirestorePigeonFirebaseApp pigeonApp) { synchronized (FlutterFirebaseFirestorePlugin.firestoreInstanceCache) { - if (FlutterFirebaseFirestorePlugin.getFirestoreInstanceByNameAndDatabaseUrl( - pigeonApp.getAppName(), pigeonApp.getDatabaseURL()) - != null) { - return FlutterFirebaseFirestorePlugin.getFirestoreInstanceByNameAndDatabaseUrl( - pigeonApp.getAppName(), pigeonApp.getDatabaseURL()); + FirebaseFirestore cachedFirestoreInstance = + FlutterFirebaseFirestorePlugin.getFirestoreInstanceByNameAndDatabaseUrl( + pigeonApp.getAppName(), pigeonApp.getDatabaseURL()); + if (cachedFirestoreInstance != null) { + return cachedFirestoreInstance; } FirebaseApp app = FirebaseApp.getInstance(pigeonApp.getAppName()); diff --git a/packages/firebase_core/firebase_core/ios/firebase_sdk_version.rb b/packages/firebase_core/firebase_core/ios/firebase_sdk_version.rb index b4948a2ae0ce..ef11fb1d055b 100644 --- a/packages/firebase_core/firebase_core/ios/firebase_sdk_version.rb +++ b/packages/firebase_core/firebase_core/ios/firebase_sdk_version.rb @@ -1,4 +1,4 @@ # https://firebase.google.com/support/release-notes/ios def firebase_sdk_version!() - '11.2.0' + '11.4.0' end diff --git a/packages/firebase_database/firebase_database_web/lib/src/interop/database.dart b/packages/firebase_database/firebase_database_web/lib/src/interop/database.dart index b2b366a0fa52..f616f00b1852 100755 --- a/packages/firebase_database/firebase_database_web/lib/src/interop/database.dart +++ b/packages/firebase_database/firebase_database_web/lib/src/interop/database.dart @@ -482,7 +482,6 @@ class Query extends JsObjectWrapper { streamController = StreamController.broadcast( onListen: startListen, onCancel: stopListen, - sync: true, ); return streamController.stream; } diff --git a/packages/firebase_messaging/firebase_messaging/ios/Classes/FLTFirebaseMessagingPlugin.m b/packages/firebase_messaging/firebase_messaging/ios/Classes/FLTFirebaseMessagingPlugin.m index 4a80cfd1a537..00c7400a3680 100644 --- a/packages/firebase_messaging/firebase_messaging/ios/Classes/FLTFirebaseMessagingPlugin.m +++ b/packages/firebase_messaging/firebase_messaging/ios/Classes/FLTFirebaseMessagingPlugin.m @@ -26,7 +26,6 @@ @implementation FLTFirebaseMessagingPlugin { NSObject *_registrar; NSData *_apnsToken; NSDictionary *_initialNotification; - bool simulatorToken; // Used to track if everything as been initialized before answering // to the initialNotification request @@ -57,7 +56,6 @@ - (instancetype)initWithFlutterMethodChannel:(FlutterMethodChannel *)channel _initialNotificationGathered = NO; _channel = channel; _registrar = registrar; - simulatorToken = false; // Application // Dart -> `getInitialNotification` // ObjC -> Initialize other delegates & observers @@ -1005,29 +1003,12 @@ + (NSDictionary *)remoteMessageUserInfoToDict:(NSDictionary *)userInfo { - (void)ensureAPNSTokenSetting { FIRMessaging *messaging = [FIRMessaging messaging]; - // With iOS SDK >= 10.4, an APNS token is required for getting/deleting token. We set a dummy - // token for the simulator for test environments. Historically, a simulator will not work for - // messaging. It will work if environment: iOS 16, running on macOS 13+ & silicon chip. We check - // the `_apnsToken` is nil. If it is, then the environment does not support and we set dummy - // token. -#if TARGET_IPHONE_SIMULATOR - if (simulatorToken == false && _apnsToken == nil) { - NSString *str = @"fake-apns-token-for-simulator"; - NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding]; - [[FIRMessaging messaging] setAPNSToken:data type:FIRMessagingAPNSTokenTypeSandbox]; - } - // We set this either way. We set dummy token once as `_apnsToken` could be nil next time - // which could possibly set dummy token unnecessarily - simulatorToken = true; -#endif - if (messaging.APNSToken == nil && _apnsToken != nil) { #ifdef DEBUG [[FIRMessaging messaging] setAPNSToken:_apnsToken type:FIRMessagingAPNSTokenTypeSandbox]; #else [[FIRMessaging messaging] setAPNSToken:_apnsToken type:FIRMessagingAPNSTokenTypeProd]; #endif - _apnsToken = nil; } } diff --git a/packages/firebase_remote_config/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/FirebaseRemoteConfigPlugin.java b/packages/firebase_remote_config/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/FirebaseRemoteConfigPlugin.java index fac40f28391f..9a3e53e07191 100644 --- a/packages/firebase_remote_config/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/FirebaseRemoteConfigPlugin.java +++ b/packages/firebase_remote_config/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/FirebaseRemoteConfigPlugin.java @@ -128,10 +128,7 @@ private void tearDownChannel() { channel = null; eventChannel.setStreamHandler(null); eventChannel = null; - for (ConfigUpdateListenerRegistration listener : listenersMap.values()) { - listener.remove(); - listenersMap.remove(listener); - } + removeEventListeners(); } private FirebaseRemoteConfig getRemoteConfig(Map arguments) { diff --git a/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/method_channel/method_channel_firebase_remote_config.dart b/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/method_channel/method_channel_firebase_remote_config.dart index f916e466fc49..4cc08ba89d74 100644 --- a/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/method_channel/method_channel_firebase_remote_config.dart +++ b/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/method_channel/method_channel_firebase_remote_config.dart @@ -293,13 +293,17 @@ class MethodChannelFirebaseRemoteConfig extends FirebaseRemoteConfigPlatform { static const EventChannel _eventChannelConfigUpdated = EventChannel('plugins.flutter.io/firebase_remote_config_updated'); + Stream? _onConfigUpdatedStream; + @override Stream get onConfigUpdated { - return _eventChannelConfigUpdated.receiveBroadcastStream({ + _onConfigUpdatedStream ??= + _eventChannelConfigUpdated.receiveBroadcastStream({ 'appName': app.name, }).map((event) { final updatedKeys = Set.from(event); return RemoteConfigUpdate(updatedKeys); }); + return _onConfigUpdatedStream!; } } diff --git a/packages/firebase_vertexai/firebase_vertexai/lib/src/error.dart b/packages/firebase_vertexai/firebase_vertexai/lib/src/error.dart index 99adc850effc..c13a434d7610 100644 --- a/packages/firebase_vertexai/firebase_vertexai/lib/src/error.dart +++ b/packages/firebase_vertexai/firebase_vertexai/lib/src/error.dart @@ -56,12 +56,16 @@ final class ServiceApiNotEnabled implements VertexAIException { 'The Vertex AI in Firebase SDK requires the Vertex AI in Firebase API ' '(`firebasevertexai.googleapis.com`) to be enabled in your Firebase project. Enable this API ' 'by visiting the Firebase Console at ' - 'https://console.firebase.google.com/$_projectId/genai ' + 'https://console.firebase.google.com/project/$_id/genai ' 'and clicking "Get started". If you enabled this API recently, wait a few minutes for the ' 'action to propagate to our systems and then retry.'; @override String toString() => message; + + String get _id { + return _projectId.replaceAll('projects/', ''); + } } /// Exception thrown when the quota is exceeded. diff --git a/tests/integration_test/firebase_analytics/firebase_analytics_e2e_test.dart b/tests/integration_test/firebase_analytics/firebase_analytics_e2e_test.dart index dc53117841ef..acb136e6a27f 100644 --- a/tests/integration_test/firebase_analytics/firebase_analytics_e2e_test.dart +++ b/tests/integration_test/firebase_analytics/firebase_analytics_e2e_test.dart @@ -9,6 +9,9 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:tests/firebase_options.dart'; +// ignore: do_not_use_environment +const bool skipTestsOnCI = bool.fromEnvironment('CI'); + void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); @@ -40,6 +43,7 @@ void main() { expect(result, isA()); } }, + skip: skipTestsOnCI && defaultTargetPlatform == TargetPlatform.iOS, ); test('isSupported', () async { diff --git a/tests/integration_test/firebase_messaging/firebase_messaging_e2e_test.dart b/tests/integration_test/firebase_messaging/firebase_messaging_e2e_test.dart index 30aa793861c1..28e92985ba04 100644 --- a/tests/integration_test/firebase_messaging/firebase_messaging_e2e_test.dart +++ b/tests/integration_test/firebase_messaging/firebase_messaging_e2e_test.dart @@ -124,13 +124,6 @@ void main() { skip: defaultTargetPlatform != TargetPlatform.android, ); - test( - 'resolves dummy APNS token on ios if using simulator', - () async { - expect(await messaging.getAPNSToken(), isA()); - }, - skip: defaultTargetPlatform != TargetPlatform.iOS, - ); }); group('getInitialMessage', () { @@ -178,9 +171,8 @@ void main() { }, // macOS skipped because it needs keychain sharing entitlement. See: https://github.com/firebase/flutterfire/issues/9538 // android skipped due to consistently failing, works locally: https://github.com/firebase/flutterfire/pull/11260 - skip: kIsWeb || - defaultTargetPlatform == TargetPlatform.macOS || - defaultTargetPlatform == TargetPlatform.android, + // iOS fails because APNS token handler doesn't have a chance to receive token before calling this method + skip: kIsWeb || skipTestsOnCI, ); }); @@ -193,9 +185,8 @@ void main() { }, // macOS skipped because it needs keychain sharing entitlement. See: https://github.com/firebase/flutterfire/issues/9538 // android skipped due to consistently failing, works locally: https://github.com/firebase/flutterfire/pull/11260 - skip: kIsWeb || - defaultTargetPlatform == TargetPlatform.macOS || - defaultTargetPlatform == TargetPlatform.android, + // iOS fails because APNS token handler doesn't have a chance to receive token before calling this method + skip: kIsWeb || skipTestsOnCI, ); });