From 79610162460b8877f3bc727464a7065106f08079 Mon Sep 17 00:00:00 2001 From: Russell Wheatley Date: Thu, 30 Jun 2022 18:14:39 +0100 Subject: [PATCH] feat: Bump Firebase iOS SDK to `9.2.0` (#8594) --- .github/workflows/e2e_tests.yaml | 2 +- .../cloud_firestore/example/ios/Podfile | 3 +- .../cloud_firestore/example/macos/Podfile | 3 +- .../ios/Classes/FLTFirebaseFunctionsPlugin.m | 16 +++- .../Classes/FirebaseInstallationsPlugin.swift | 3 +- .../ios/Classes/FLTFirebasePluginRegistry.m | 10 ++- .../firebase_core/ios/firebase_sdk_version.rb | 2 +- .../Classes/FLTFirebaseDynamicLinksPlugin.m | 11 +++ .../firebase_ml_model_downloader.podspec | 4 +- .../firebase_performance/example/ios/Podfile | 41 +++++++++ .../ios/Classes/FLTFirebaseStoragePlugin.m | 2 +- tests/ios/Podfile | 3 +- tests/ios/Runner.xcodeproj/project.pbxproj | 44 ++++++---- tests/ios/Runner/Info.plist | 4 + tests/ios/Runner/Runner.entitlements | 10 +++ tests/macos/Podfile | 3 +- .../firebase_dynamic_links_e2e.dart | 34 +++++++- .../firebase_remote_config_e2e.dart | 85 +++++++++++-------- 18 files changed, 206 insertions(+), 74 deletions(-) create mode 100644 packages/firebase_performance/firebase_performance/example/ios/Podfile create mode 100644 tests/ios/Runner/Runner.entitlements diff --git a/.github/workflows/e2e_tests.yaml b/.github/workflows/e2e_tests.yaml index 4ed79212329f..65ca244ed91e 100644 --- a/.github/workflows/e2e_tests.yaml +++ b/.github/workflows/e2e_tests.yaml @@ -114,7 +114,7 @@ jobs: ios: - runs-on: macos-latest + runs-on: macos-12 timeout-minutes: 45 steps: - uses: actions/checkout@v2 diff --git a/packages/cloud_firestore/cloud_firestore/example/ios/Podfile b/packages/cloud_firestore/cloud_firestore/example/ios/Podfile index 16f042b82cf6..b0a98436b7d5 100644 --- a/packages/cloud_firestore/cloud_firestore/example/ios/Podfile +++ b/packages/cloud_firestore/cloud_firestore/example/ios/Podfile @@ -51,7 +51,8 @@ target 'Runner' do end end - pod 'FirebaseFirestore', :git => 'https://github.com/invertase/firestore-ios-sdk-frameworks.git', :tag => "#{firebase_sdk_version}" + # TODO - replace with #{firebase_sdk_version} once it has been released on: https://github.com/invertase/firestore-ios-sdk-frameworks.git + pod 'FirebaseFirestore', :git => 'https://github.com/invertase/firestore-ios-sdk-frameworks.git', :branch => 'main' end post_install do |installer| diff --git a/packages/cloud_firestore/cloud_firestore/example/macos/Podfile b/packages/cloud_firestore/cloud_firestore/example/macos/Podfile index d4aecc79930a..7c06274c7632 100644 --- a/packages/cloud_firestore/cloud_firestore/example/macos/Podfile +++ b/packages/cloud_firestore/cloud_firestore/example/macos/Podfile @@ -50,7 +50,8 @@ target 'Runner' do end end - pod 'FirebaseFirestore', :git => 'https://github.com/invertase/firestore-ios-sdk-frameworks.git', :tag => "#{firebase_sdk_version}" + # TODO - replace with #{firebase_sdk_version} once it has been released on: https://github.com/invertase/firestore-ios-sdk-frameworks.git + pod 'FirebaseFirestore', :git => 'https://github.com/invertase/firestore-ios-sdk-frameworks.git', :branch => 'main' end post_install do |installer| diff --git a/packages/cloud_functions/cloud_functions/ios/Classes/FLTFirebaseFunctionsPlugin.m b/packages/cloud_functions/cloud_functions/ios/Classes/FLTFirebaseFunctionsPlugin.m index 5b1f90c50d6e..810a62310d13 100644 --- a/packages/cloud_functions/cloud_functions/ios/Classes/FLTFirebaseFunctionsPlugin.m +++ b/packages/cloud_functions/cloud_functions/ios/Classes/FLTFirebaseFunctionsPlugin.m @@ -50,10 +50,17 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)flutter NSMutableDictionary *httpsErrorDetails = [NSMutableDictionary dictionary]; NSString *httpsErrorCode = [NSString stringWithFormat:@"%ld", error.code]; NSString *httpsErrorMessage = error.localizedDescription; - if (error.domain == FIRFunctionsErrorDomain) { + // FIRFunctionsErrorDomain has been removed and replaced with Swift implementation + // https://github.com/firebase/firebase-ios-sdk/blob/master/FirebaseFunctions/Sources/FunctionsError.swift#L18 + NSString *errorDomain = @"com.firebase.functions"; + // FIRFunctionsErrorDetailsKey has been deprecated and replaced with Swift implementation + // https://github.com/firebase/firebase-ios-sdk/blob/master/FirebaseFunctions/Sources/FunctionsError.swift#L21 + NSString *detailsKey = @"details"; + // See also https://github.com/firebase/firebase-ios-sdk/pull/9569 + if ([error.domain isEqualToString:errorDomain]) { httpsErrorCode = [self mapFunctionsErrorCodes:error.code]; - if (error.userInfo[FIRFunctionsErrorDetailsKey] != nil) { - httpsErrorDetails[@"additionalData"] = error.userInfo[FIRFunctionsErrorDetailsKey]; + if (error.userInfo[detailsKey] != nil) { + httpsErrorDetails[@"additionalData"] = error.userInfo[detailsKey]; } } httpsErrorDetails[@"code"] = httpsErrorCode; @@ -82,7 +89,8 @@ - (void)httpsFunctionCall:(id)arguments withMethodCallResult:(FLTFirebaseMethodC FIRApp *app = [FLTFirebasePlugin firebaseAppNamed:appName]; FIRFunctions *functions = [FIRFunctions functionsForApp:app region:region]; if (origin != nil && origin != (id)[NSNull null]) { - [functions useFunctionsEmulatorOrigin:origin]; + NSURL *url = [NSURL URLWithString:origin]; + [functions useEmulatorWithHost:[url host] port:[[url port] intValue]]; } FIRHTTPSCallable *function = [functions HTTPSCallableWithName:functionName]; diff --git a/packages/firebase_app_installations/firebase_app_installations/ios/Classes/FirebaseInstallationsPlugin.swift b/packages/firebase_app_installations/firebase_app_installations/ios/Classes/FirebaseInstallationsPlugin.swift index 47b01b46ee5e..71df874438eb 100644 --- a/packages/firebase_app_installations/firebase_app_installations/ios/Classes/FirebaseInstallationsPlugin.swift +++ b/packages/firebase_app_installations/firebase_app_installations/ios/Classes/FirebaseInstallationsPlugin.swift @@ -112,7 +112,8 @@ public class FirebaseInstallationsPluginSwift: FLTFirebasePlugin, FlutterPlugin } internal func mapInstallationsErrorCodes(code: UInt) -> NSString { - let error = InstallationsErrorCode(rawValue: code) ?? InstallationsErrorCode.unknown + let error = InstallationsErrorCode(InstallationsErrorCode + .Code(rawValue: Int(code)) ?? InstallationsErrorCode.unknown) switch error { case InstallationsErrorCode.invalidConfiguration: diff --git a/packages/firebase_core/firebase_core/ios/Classes/FLTFirebasePluginRegistry.m b/packages/firebase_core/firebase_core/ios/Classes/FLTFirebasePluginRegistry.m index f2ef868f8445..234fb5e9d412 100644 --- a/packages/firebase_core/firebase_core/ios/Classes/FLTFirebasePluginRegistry.m +++ b/packages/firebase_core/firebase_core/ios/Classes/FLTFirebasePluginRegistry.m @@ -3,7 +3,14 @@ // found in the LICENSE file. #import "FLTFirebasePluginRegistry.h" + +#if __has_include() #import +#define REGISTER_LIB +#elif __has_include() +#import +#define REGISTER_LIB +#endif @implementation FLTFirebasePluginRegistry { NSMutableDictionary> *registeredPlugins; @@ -30,9 +37,10 @@ + (instancetype)sharedInstance { - (void)registerFirebasePlugin:(id)firebasePlugin { // Register the library with the Firebase backend. +#ifdef REGISTER_LIB [FIRApp registerLibrary:[firebasePlugin firebaseLibraryName] withVersion:[firebasePlugin firebaseLibraryVersion]]; - +#endif // Store the plugin delegate for later usage. registeredPlugins[[firebasePlugin flutterChannelName]] = firebasePlugin; } 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 f44056bf7904..cbe59b88f317 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!() - '8.15.0' + '9.2.0' end diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m index 47e01ddd7bd9..821542d1833a 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m @@ -128,6 +128,17 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result code = errorDetails[kCode]; message = errorDetails[kMessage]; details = errorDetails; + + if (errorDetails[@"additionalData"][NSLocalizedFailureReasonErrorKey] != nil) { + // This stops an uncaught type cast exception in dart + NSMutableDictionary *temp = [errorDetails[@"additionalData"] mutableCopy]; + [temp removeObjectForKey:NSLocalizedFailureReasonErrorKey]; + details = temp; + // provides a useful message to the user. e.g. "Universal link URL could not be parsed". + if ([message containsString:@"unknown error"]) { + message = errorDetails[@"additionalData"][NSLocalizedFailureReasonErrorKey]; + } + } } else { details = @{ kCode : code, diff --git a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/macos/firebase_ml_model_downloader.podspec b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/macos/firebase_ml_model_downloader.podspec index 7c8939058f42..be0dbaec8655 100644 --- a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/macos/firebase_ml_model_downloader.podspec +++ b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader/macos/firebase_ml_model_downloader.podspec @@ -52,9 +52,7 @@ Pod::Spec.new do |s| # Firebase dependencies s.dependency 'Firebase/CoreOnly', "~> #{firebase_sdk_version}" - # TODO(Salakar): Direct pod depency here instead of the Firebase subspec due to: - # https://github.com/firebase/firebase-ios-sdk/pull/9186 (pending acceptance / merge) - s.dependency 'FirebaseMLModelDownloader', '~> 8.10.0-beta' + s.dependency 'Firebase/MLModelDownloader', firebase_sdk_version s.static_framework = true s.swift_version = '5.0' s.pod_target_xcconfig = { diff --git a/packages/firebase_performance/firebase_performance/example/ios/Podfile b/packages/firebase_performance/firebase_performance/example/ios/Podfile new file mode 100644 index 000000000000..1e8c3c90a55e --- /dev/null +++ b/packages/firebase_performance/firebase_performance/example/ios/Podfile @@ -0,0 +1,41 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/packages/firebase_storage/firebase_storage/ios/Classes/FLTFirebaseStoragePlugin.m b/packages/firebase_storage/firebase_storage/ios/Classes/FLTFirebaseStoragePlugin.m index dd4ade6c8c77..8223b78d72e8 100644 --- a/packages/firebase_storage/firebase_storage/ios/Classes/FLTFirebaseStoragePlugin.m +++ b/packages/firebase_storage/firebase_storage/ios/Classes/FLTFirebaseStoragePlugin.m @@ -4,8 +4,8 @@ #import #import +#import #import - #import "FLTFirebaseStoragePlugin.h" static NSString *const kFLTFirebaseStorageChannelName = @"plugins.flutter.io/firebase_storage"; diff --git a/tests/ios/Podfile b/tests/ios/Podfile index 706431681379..31a9b996cbb5 100644 --- a/tests/ios/Podfile +++ b/tests/ios/Podfile @@ -47,7 +47,8 @@ target 'Runner' do end end - pod 'FirebaseFirestore', :git => 'https://github.com/invertase/firestore-ios-sdk-frameworks.git', :tag => "#{firebase_sdk_version}" + # TODO - replace with #{firebase_sdk_version} once it has been released on: https://github.com/invertase/firestore-ios-sdk-frameworks.git + pod 'FirebaseFirestore', :git => 'https://github.com/invertase/firestore-ios-sdk-frameworks.git', :branch => 'main' end post_install do |installer| diff --git a/tests/ios/Runner.xcodeproj/project.pbxproj b/tests/ios/Runner.xcodeproj/project.pbxproj index a2947fd4def9..c3b86276b0e3 100644 --- a/tests/ios/Runner.xcodeproj/project.pbxproj +++ b/tests/ios/Runner.xcodeproj/project.pbxproj @@ -34,6 +34,7 @@ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 29DCF5BB48C5B80F2EE02483 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 46682439286310F7005ADD39 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; 56B65A6814148F63F80E1BCD /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -112,6 +113,7 @@ 97C146F01CF9000F007C117D /* Runner */ = { isa = PBXGroup; children = ( + 46682439286310F7005ADD39 /* Runner.entitlements */, 97C146FA1CF9000F007C117D /* Main.storyboard */, 97C146FD1CF9000F007C117D /* Assets.xcassets */, 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, @@ -139,8 +141,8 @@ 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, AC660AAB7696B4DD121B84D0 /* [CP] Embed Pods Frameworks */, - AFACAC31EEE064D50881C495 /* [CP] Copy Pods Resources */, 5F39B4E393588B005ADEE74A /* [firebase_crashlytics] Crashlytics Upload Symbols */, + 570B63470F19A77487B49310 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -213,6 +215,23 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; + 570B63470F19A77487B49310 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 5F39B4E393588B005ADEE74A /* [firebase_crashlytics] Crashlytics Upload Symbols */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -286,23 +305,6 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - AFACAC31EEE064D50881C495 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -393,7 +395,9 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = YYX2P3XVJ7; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -521,7 +525,9 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = YYX2P3XVJ7; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -543,7 +549,9 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = YYX2P3XVJ7; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( diff --git a/tests/ios/Runner/Info.plist b/tests/ios/Runner/Info.plist index d4d758c12e68..fa98392a8edb 100644 --- a/tests/ios/Runner/Info.plist +++ b/tests/ios/Runner/Info.plist @@ -63,5 +63,9 @@ CADisableMinimumFrameDurationOnPhone + FirebaseDynamicLinksCustomDomains + + https://flutterfiretests.page.link/** + diff --git a/tests/ios/Runner/Runner.entitlements b/tests/ios/Runner/Runner.entitlements new file mode 100644 index 000000000000..d7ab8334dfa2 --- /dev/null +++ b/tests/ios/Runner/Runner.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.developer.associated-domains + + applinks:flutterfiretests.page.link + + + diff --git a/tests/macos/Podfile b/tests/macos/Podfile index 7c2d8821704c..81c212c31ed9 100644 --- a/tests/macos/Podfile +++ b/tests/macos/Podfile @@ -46,7 +46,8 @@ target 'Runner' do end end - pod 'FirebaseFirestore', :git => 'https://github.com/invertase/firestore-ios-sdk-frameworks.git', :tag => "#{firebase_sdk_version}" + # TODO - replace with #{firebase_sdk_version} once it has been released on: https://github.com/invertase/firestore-ios-sdk-frameworks.git + pod 'FirebaseFirestore', :git => 'https://github.com/invertase/firestore-ios-sdk-frameworks.git', :branch => 'main' end post_install do |installer| diff --git a/tests/test_driver/firebase_dynamic_links/firebase_dynamic_links_e2e.dart b/tests/test_driver/firebase_dynamic_links/firebase_dynamic_links_e2e.dart index d7335436900e..3893b9df26ca 100644 --- a/tests/test_driver/firebase_dynamic_links/firebase_dynamic_links_e2e.dart +++ b/tests/test_driver/firebase_dynamic_links/firebase_dynamic_links_e2e.dart @@ -134,12 +134,40 @@ void setupTests() { }); group('getDynamicLink', () { - test('dynamic link using uri', () async { - Uri uri = Uri.parse(''); + test('dynamic link using uri created on Firebase console', () async { + // Link created in Firebase console + Uri uri = Uri.parse('https://flutterfiretests.page.link/iho8'); PendingDynamicLinkData? pendingLink = await FirebaseDynamicLinks.instance.getDynamicLink(uri); - expect(pendingLink, isNull); + expect(pendingLink, isA()); + expect(pendingLink?.link.toString(), 'https://example/helloworld'); }); + + test( + 'Universal link error for URL that cannot be parsed', + () async { + Uri uri = Uri.parse(''); + if (defaultTargetPlatform == TargetPlatform.iOS) { + await expectLater( + FirebaseDynamicLinks.instance.getDynamicLink(uri), + throwsA( + isA().having( + (e) => e.message, + 'message', + contains('could not be parsed'), + ), + ), + ); + } else if (defaultTargetPlatform == TargetPlatform.android) { + // TODO - android returns normally. Throw error to keep consistent with iOS or catch on iOS and return `null`. + // Internal ticket created: https://linear.app/invertase/issue/FF-44/dynamic-link-univeral-link-cannot-be-parsed + await expectLater( + FirebaseDynamicLinks.instance.getDynamicLink(uri), + completes, + ); + } + }, + ); }); group('onLink', () { diff --git a/tests/test_driver/firebase_remote_config/firebase_remote_config_e2e.dart b/tests/test_driver/firebase_remote_config/firebase_remote_config_e2e.dart index b7af46a10676..0c71d9a66d42 100644 --- a/tests/test_driver/firebase_remote_config/firebase_remote_config_e2e.dart +++ b/tests/test_driver/firebase_remote_config/firebase_remote_config_e2e.dart @@ -6,6 +6,7 @@ import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_remote_config/firebase_remote_config.dart'; import 'package:drive/drive.dart'; +import 'package:flutter/foundation.dart'; import '../firebase_default_options.dart'; void setupTests() { @@ -28,46 +29,56 @@ void setupTests() { await FirebaseRemoteConfig.instance.ensureInitialized(); }); - test('fetch', () async { - final mark = DateTime.now(); - expect( - FirebaseRemoteConfig.instance.lastFetchTime.isBefore(mark), - true, - ); - await FirebaseRemoteConfig.instance.fetchAndActivate(); - expect( - FirebaseRemoteConfig.instance.lastFetchStatus, - RemoteConfigFetchStatus.success, - ); - expect(FirebaseRemoteConfig.instance.lastFetchTime.isAfter(mark), true); - expect( - FirebaseRemoteConfig.instance.getString('string'), - 'flutterfire', - ); - expect(FirebaseRemoteConfig.instance.getBool('bool'), isTrue); - expect(FirebaseRemoteConfig.instance.getInt('int'), 123); - expect(FirebaseRemoteConfig.instance.getDouble('double'), 123.456); - expect( - FirebaseRemoteConfig.instance.getValue('string').source, - ValueSource.valueRemote, - ); + test( + 'fetch', + () async { + final mark = DateTime.now(); + expect( + FirebaseRemoteConfig.instance.lastFetchTime.isBefore(mark), + true, + ); - expect( - FirebaseRemoteConfig.instance.getString('hello'), - 'default hello', - ); - expect( - FirebaseRemoteConfig.instance.getValue('hello').source, - ValueSource.valueDefault, - ); + await FirebaseRemoteConfig.instance.fetchAndActivate(); - expect(FirebaseRemoteConfig.instance.getInt('nonexisting'), 0); + expect( + FirebaseRemoteConfig.instance.lastFetchStatus, + RemoteConfigFetchStatus.success, + ); + expect( + FirebaseRemoteConfig.instance.lastFetchTime.isAfter(mark), + true, + ); + expect( + FirebaseRemoteConfig.instance.getString('string'), + 'flutterfire', + ); + expect(FirebaseRemoteConfig.instance.getBool('bool'), isTrue); + expect(FirebaseRemoteConfig.instance.getInt('int'), 123); + expect(FirebaseRemoteConfig.instance.getDouble('double'), 123.456); + expect( + FirebaseRemoteConfig.instance.getValue('string').source, + ValueSource.valueRemote, + ); - expect( - FirebaseRemoteConfig.instance.getValue('nonexisting').source, - ValueSource.valueStatic, - ); - }); + expect( + FirebaseRemoteConfig.instance.getString('hello'), + 'default hello', + ); + expect( + FirebaseRemoteConfig.instance.getValue('hello').source, + ValueSource.valueDefault, + ); + + expect(FirebaseRemoteConfig.instance.getInt('nonexisting'), 0); + + expect( + FirebaseRemoteConfig.instance.getValue('nonexisting').source, + ValueSource.valueStatic, + ); + }, + // iOS v9.2.0 hangs on ci if `fetchAndActivate()` is used, but works locally. + skip: defaultTargetPlatform == TargetPlatform.iOS, + ); test('settings', () async { expect(