Skip to content

Commit 4afbee4

Browse files
committed
feat(ios)!: forward port to firebase-ios-sdk v7.3.0
remote-config debugMode is removed, use minimumFetchInterval instead this should work on ios and android platforms
1 parent 3459da0 commit 4afbee4

File tree

10 files changed

+108
-48
lines changed

10 files changed

+108
-48
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
def firebase_sdk_version!()
2-
'6.33.0'
2+
'7.3.0'
33
end

packages/firebase_messaging/firebase_messaging/ios/Classes/FLTFirebaseMessagingPlugin.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ - (void)messagingSetForegroundNotificationPresentationOptions:(id)arguments
164164
#pragma mark - Firebase Messaging Delegate
165165

166166
- (void)messaging:(nonnull FIRMessaging *)messaging
167-
didReceiveRegistrationToken:(nonnull NSString *)fcmToken {
167+
didReceiveRegistrationToken:(nullable NSString *)fcmToken {
168168
// Don't crash if the token is reset.
169169
if (fcmToken == nil) {
170170
return;

packages/firebase_ml_vision/example/ios/Podfile

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,3 @@ post_install do |installer|
3737
end
3838
end
3939

40-
pod 'Firebase/MLVisionBarcodeModel'
41-
pod 'Firebase/MLVisionFaceModel'
42-
pod 'Firebase/MLVisionLabelModel'
43-
pod 'Firebase/MLVisionTextModel'

packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/MethodCallHandlerImpl.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,28 @@ public void onMethodCall(MethodCall call, final MethodChannel.Result result) {
4242
properties.put(
4343
"lastFetchStatus", mapLastFetchStatus(firebaseRemoteConfigInfo.getLastFetchStatus()));
4444
properties.put(
45-
"inDebugMode", firebaseRemoteConfigInfo.getConfigSettings().isDeveloperModeEnabled());
45+
"minimumFetchInterval",
46+
firebaseRemoteConfigInfo.getConfigSettings().getMinimumFetchIntervalInSeconds());
47+
properties.put(
48+
"fetchTimeout",
49+
firebaseRemoteConfigInfo.getConfigSettings().getFetchTimeoutInSeconds());
4650
properties.put("parameters", getConfigParameters());
4751
result.success(properties);
4852
break;
4953
}
5054
case "RemoteConfig#setConfigSettings":
5155
{
52-
boolean debugMode = call.argument("debugMode");
5356
final FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
54-
FirebaseRemoteConfigSettings settings =
55-
new FirebaseRemoteConfigSettings.Builder().setDeveloperModeEnabled(debugMode).build();
56-
firebaseRemoteConfig.setConfigSettings(settings);
57+
FirebaseRemoteConfigSettings.Builder configSettingsBuilder =
58+
new FirebaseRemoteConfigSettings.Builder();
59+
if (call.argument("minimumFetchInterval") != null) {
60+
configSettingsBuilder.setMinimumFetchIntervalInSeconds(
61+
(int) call.argument("minimumFetchInterval"));
62+
}
63+
if (call.argument("fetchTimeout") != null) {
64+
configSettingsBuilder.setFetchTimeoutInSeconds((int) call.argument("fetchTimeout"));
65+
}
66+
firebaseRemoteConfig.setConfigSettingsAsync(configSettingsBuilder.build());
5767
result.success(null);
5868
break;
5969
}

packages/firebase_remote_config/example/lib/main.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,9 @@ class WelcomeWidget extends AnimatedWidget {
5757
Future<RemoteConfig> setupRemoteConfig() async {
5858
await Firebase.initializeApp();
5959
final RemoteConfig remoteConfig = await RemoteConfig.instance;
60-
// Enable developer mode to relax fetch throttling
61-
remoteConfig.setConfigSettings(RemoteConfigSettings(debugMode: true));
60+
// Allow a fetch every millisecond. Default is 12 hours.
61+
remoteConfig
62+
.setConfigSettings(RemoteConfigSettings(minimumFetchIntervalMillis: 1));
6263
remoteConfig.setDefaults(<String, dynamic>{
6364
'welcome': 'default welcome',
6465
'hello': 'default hello',

packages/firebase_remote_config/example/test_driver/firebase_remote_config_e2e.dart

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ void main() {
1212
setUp(() async {
1313
await Firebase.initializeApp();
1414
remoteConfig = await RemoteConfig.instance;
15-
await remoteConfig
16-
.setConfigSettings(RemoteConfigSettings(debugMode: true));
15+
// Set our config to no minimum fetch interval so that settings change immediately
16+
await remoteConfig.setConfigSettings(RemoteConfigSettings(
17+
minimumFetchIntervalMillis: 0, fetchTimeoutMillis: 30 * 1000));
1718
await remoteConfig.setDefaults(<String, dynamic>{
1819
'welcome': 'default welcome',
1920
'hello': 'default hello',
@@ -25,14 +26,18 @@ void main() {
2526
expect(lastFetchTime.isBefore(DateTime.now()), true);
2627
await remoteConfig.fetch(expiration: const Duration(seconds: 0));
2728
expect(remoteConfig.lastFetchStatus, LastFetchStatus.success);
28-
await remoteConfig.activateFetched();
29+
final activated = await remoteConfig.activateFetched();
30+
expect(activated, true);
2931

32+
// TODO should verify that our config settings actually took
3033
expect(remoteConfig.getString('welcome'), 'Earth, welcome! Hello!');
34+
expect(remoteConfig.getValue('welcome').source, ValueSource.valueRemote);
35+
3136
expect(remoteConfig.getString('hello'), 'default hello');
37+
expect(remoteConfig.getValue('hello').source, ValueSource.valueDefault);
38+
3239
expect(remoteConfig.getInt('nonexisting'), 0);
3340

34-
expect(remoteConfig.getValue('welcome').source, ValueSource.valueRemote);
35-
expect(remoteConfig.getValue('hello').source, ValueSource.valueDefault);
3641
expect(
3742
remoteConfig.getValue('nonexisting').source,
3843
ValueSource.valueStatic,

packages/firebase_remote_config/ios/Classes/FirebaseRemoteConfigPlugin.m

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,24 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result
4040
initWithLong:(long)[[remoteConfig lastFetchTime] timeIntervalSince1970] * 1000];
4141
resultDict[@"lastFetchStatus"] =
4242
[self mapLastFetchStatus:(FIRRemoteConfigFetchStatus)[remoteConfig lastFetchStatus]];
43-
resultDict[@"inDebugMode"] =
44-
[[NSNumber alloc] initWithBool:[firRemoteConfigSettings isDeveloperModeEnabled]];
43+
resultDict[@"minimumFetchInterval"] =
44+
[[NSNumber alloc] initWithLong:(long)[firRemoteConfigSettings minimumFetchInterval]];
45+
resultDict[@"fetchTimeout"] =
46+
[[NSNumber alloc] initWithLong:(long)[firRemoteConfigSettings fetchTimeout]];
4547

4648
resultDict[@"parameters"] = [self getConfigParameters];
4749

4850
result(resultDict);
4951
} else if ([@"RemoteConfig#setConfigSettings" isEqualToString:call.method]) {
5052
FIRRemoteConfig *remoteConfig = [FIRRemoteConfig remoteConfig];
51-
bool debugMode = (bool)call.arguments[@"debugMode"];
52-
FIRRemoteConfigSettings *remoteConfigSettings =
53-
[[FIRRemoteConfigSettings alloc] initWithDeveloperModeEnabled:debugMode];
53+
FIRRemoteConfigSettings *remoteConfigSettings = [[FIRRemoteConfigSettings alloc] init];
54+
if ([call.arguments objectForKey:@"minimumFetchInterval"]) {
55+
remoteConfigSettings.minimumFetchInterval =
56+
[call.arguments[@"minimumFetchInterval"] longValue];
57+
}
58+
if ([call.arguments objectForKey:@"fetchTimeout"]) {
59+
remoteConfigSettings.fetchTimeout = [call.arguments[@"fetchTimeout"] longValue];
60+
}
5461
[remoteConfig setConfigSettings:remoteConfigSettings];
5562
result(nil);
5663
} else if ([@"RemoteConfig#fetch" isEqualToString:call.method]) {
@@ -97,12 +104,37 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result
97104
}
98105
}];
99106
} else if ([@"RemoteConfig#activate" isEqualToString:call.method]) {
100-
BOOL newConfig = [[FIRRemoteConfig remoteConfig] activateFetched];
101-
NSDictionary *parameters = [self getConfigParameters];
102-
NSMutableDictionary *resultDict = [[NSMutableDictionary alloc] init];
103-
resultDict[@"newConfig"] = [NSNumber numberWithBool:newConfig];
104-
resultDict[@"parameters"] = parameters;
105-
result(resultDict);
107+
[[FIRRemoteConfig remoteConfig]
108+
activateWithCompletion:^(BOOL changed, NSError *_Nullable error) {
109+
BOOL newConfig = YES;
110+
111+
// If the config was already activated, we get an error from the SDK.
112+
// Our goal is to map that specific error to a normal return with "false" for newConfig
113+
// All other errors are rethrown as actual errors.
114+
if (error) {
115+
NSString *failureReason = @"";
116+
if (error.userInfo && error.userInfo[@"ActivationFailureReason"] != nil) {
117+
failureReason = error.userInfo[@"ActivationFailureReason"];
118+
}
119+
if ([failureReason containsString:@"already activated"]) {
120+
newConfig = NO;
121+
} else {
122+
FlutterError *flutterError;
123+
flutterError = [FlutterError errorWithCode:@"activateFailed"
124+
message:failureReason
125+
details:nil];
126+
result(flutterError);
127+
return;
128+
}
129+
}
130+
131+
// If no real error, return all configs with boolean indicating if newly activated
132+
NSDictionary *parameters = [self getConfigParameters];
133+
NSMutableDictionary *resultDict = [[NSMutableDictionary alloc] init];
134+
resultDict[@"newConfig"] = [NSNumber numberWithBool:newConfig];
135+
resultDict[@"parameters"] = parameters;
136+
result(resultDict);
137+
}];
106138
} else if ([@"RemoteConfig#setDefaults" isEqualToString:call.method]) {
107139
FIRRemoteConfig *remoteConfig = [FIRRemoteConfig remoteConfig];
108140
NSDictionary *defaults = call.arguments[@"defaults"];
@@ -128,8 +160,7 @@ - (NSDictionary *)getConfigParameters {
128160
parameterDict[key] = [self createRemoteConfigValueDict:[remoteConfig configValueForKey:key]];
129161
}
130162
// Add default parameters if missing since `keysWithPrefix` does not return default keys.
131-
NSArray *defaultKeys = [remoteConfig allKeysFromSource:FIRRemoteConfigSourceDefault
132-
namespace:FIRNamespaceGoogleMobilePlatform];
163+
NSArray *defaultKeys = [remoteConfig allKeysFromSource:FIRRemoteConfigSourceDefault];
133164
for (NSString *key in defaultKeys) {
134165
if ([parameterDict valueForKey:key] == nil) {
135166
parameterDict[key] = [self createRemoteConfigValueDict:[remoteConfig configValueForKey:key]];

packages/firebase_remote_config/lib/src/remote_config.dart

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,9 @@ class RemoteConfig extends ChangeNotifier {
4848
DateTime.fromMillisecondsSinceEpoch(properties['lastFetchTime']);
4949
instance._lastFetchStatus =
5050
_parseLastFetchStatus(properties['lastFetchStatus']);
51-
final RemoteConfigSettings remoteConfigSettings =
52-
RemoteConfigSettings(debugMode: properties['inDebugMode']);
51+
final RemoteConfigSettings remoteConfigSettings = RemoteConfigSettings(
52+
minimumFetchIntervalMillis: (properties['minimumFetchInterval'] * 1000),
53+
fetchTimeoutMillis: (properties['fetchTimeout'] * 1000));
5354
instance._remoteConfigSettings = remoteConfigSettings;
5455
instance._parameters =
5556
_parseRemoteConfigParameters(parameters: properties['parameters']);
@@ -99,12 +100,14 @@ class RemoteConfig extends ChangeNotifier {
99100

100101
/// Set the configuration settings for this [RemoteConfig] instance.
101102
///
102-
/// This can be used for enabling developer mode.
103+
/// This can be used to set minimum fetch time and fetch timeout.
103104
Future<void> setConfigSettings(
104105
RemoteConfigSettings remoteConfigSettings) async {
105106
await channel
106107
.invokeMethod<void>('RemoteConfig#setConfigSettings', <String, dynamic>{
107-
'debugMode': remoteConfigSettings.debugMode,
108+
'minimumFetchInterval':
109+
(remoteConfigSettings.minimumFetchIntervalMillis ~/ 1000),
110+
'fetchTimeout': (remoteConfigSettings.fetchTimeoutMillis ~/ 1000)
108111
});
109112
_remoteConfigSettings = remoteConfigSettings;
110113
}

packages/firebase_remote_config/lib/src/remote_config_settings.dart

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,20 @@ part of firebase_remote_config;
66

77
/// RemoteConfigSettings can be used to configure how Remote Config operates.
88
class RemoteConfigSettings {
9-
RemoteConfigSettings({this.debugMode = false});
9+
RemoteConfigSettings(
10+
{this.minimumFetchIntervalMillis = 43200000,
11+
this.fetchTimeoutMillis = 60000});
1012

11-
/// Enable or disable developer mode for Remote Config.
13+
/// Set the minimum fetch interval for Remote Config, in milliseconds
1214
///
13-
/// When set to true developer mode is enabled, when set to false developer
14-
/// mode is disabled. When developer mode is enabled fetch throttling is
15-
/// relaxed to allow many more fetch calls per hour to the remote server than
16-
/// the 5 per hour that is enforced when developer mode is disabled.
17-
final bool debugMode;
15+
/// Indicates the default value in milliseconds to set for the minimum
16+
/// interval that needs to elapse before a fetch request can again be made
17+
/// to the Remote Config server. Defaults to 43200000 (Twelve hours).
18+
final int minimumFetchIntervalMillis;
19+
20+
/// Set the fetch timeout for Remote Config, in milliseconds
21+
///
22+
/// Indicates the default value in milliseconds to abandon a pending fetch
23+
/// request made to the Remote Config server. Defaults to 60000 (One minute).
24+
final int fetchTimeoutMillis;
1825
}

packages/firebase_remote_config/test/firebase_remote_config_test.dart

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ void main() {
1414
return <String, dynamic>{
1515
'lastFetchTime': lastFetchTime,
1616
'lastFetchStatus': 'success',
17-
'inDebugMode': true,
17+
'minimumFetchInterval': 0, // 12 hours is default, 0 seconds in test
18+
'fetchTimeout': 60, // 60 seconds is remote-config default
1819
'parameters': <String, dynamic>{
1920
'param1': <String, dynamic>{
2021
'source': 'static',
@@ -48,7 +49,8 @@ void main() {
4849
isMethodCall('RemoteConfig#instance', arguments: null),
4950
],
5051
);
51-
expect(remoteConfig.remoteConfigSettings.debugMode, true);
52+
expect(remoteConfig.remoteConfigSettings.minimumFetchIntervalMillis, 0);
53+
expect(remoteConfig.remoteConfigSettings.fetchTimeoutMillis, 60 * 1000);
5254
expect(remoteConfig.lastFetchTime,
5355
DateTime.fromMillisecondsSinceEpoch(lastFetchTime));
5456
expect(remoteConfig.lastFetchStatus, LastFetchStatus.values[0]);
@@ -218,22 +220,27 @@ void main() {
218220
});
219221

220222
test('setConfigSettings', () async {
221-
expect(remoteConfig.remoteConfigSettings.debugMode, true);
223+
var intervalSecs = 100;
224+
expect(remoteConfig.remoteConfigSettings.minimumFetchIntervalMillis, 0);
222225
final RemoteConfigSettings remoteConfigSettings =
223-
RemoteConfigSettings(debugMode: false);
226+
// milliseconds in the Dart API (to match firebase-js-sdk)
227+
RemoteConfigSettings(minimumFetchIntervalMillis: intervalSecs * 1000);
224228
await remoteConfig.setConfigSettings(remoteConfigSettings);
225229
expect(
226230
log,
227231
<Matcher>[
228232
isMethodCall(
229233
'RemoteConfig#setConfigSettings',
230234
arguments: <String, dynamic>{
231-
'debugMode': false,
235+
// milliseconds in Dart API, but just seconds for native ios/android
236+
'minimumFetchInterval': intervalSecs,
237+
'fetchTimeout': 60, // from our mock instance above
232238
},
233239
),
234240
],
235241
);
236-
expect(remoteConfig.remoteConfigSettings.debugMode, false);
242+
expect(remoteConfig.remoteConfigSettings.minimumFetchIntervalMillis,
243+
intervalSecs * 1000);
237244
});
238245
});
239246
}

0 commit comments

Comments
 (0)