7
7
8
8
#import " FLTFirebaseRemoteConfigPlugin.h"
9
9
#import " FLTFirebaseRemoteConfigUtils.h"
10
+ #import " Reachability.h"
10
11
11
12
NSString *const kFirebaseRemoteConfigChannelName = @" plugins.flutter.io/firebase_remote_config" ;
12
13
13
14
@interface FLTFirebaseRemoteConfigPlugin ()
14
15
@property (nonatomic , retain ) FlutterMethodChannel *channel;
16
+ @property (nonatomic ) Reachability *hostReachability;
15
17
@end
16
18
17
19
@implementation FLTFirebaseRemoteConfigPlugin
18
20
21
+ BOOL _canConnectToHost;
22
+ BOOL _fetchAndActivateRetry;
23
+ NSString *remoteHostName = @" firebaseremoteconfig.googleapis.com" ;
19
24
+ (instancetype )sharedInstance {
20
25
static dispatch_once_t onceToken;
21
26
static FLTFirebaseRemoteConfigPlugin *instance;
27
+ _canConnectToHost = true ;
28
+ _fetchAndActivateRetry = false ;
22
29
23
30
dispatch_once (&onceToken, ^{
24
31
instance = [[FLTFirebaseRemoteConfigPlugin alloc ] init ];
@@ -29,6 +36,13 @@ + (instancetype)sharedInstance {
29
36
}
30
37
31
38
- (instancetype )init {
39
+ self.hostReachability = [Reachability reachabilityWithHostName: remoteHostName];
40
+ [self .hostReachability startNotifier ];
41
+ [[NSNotificationCenter defaultCenter ] addObserver: self
42
+ selector: @selector (reachabilityChanged: )
43
+ name: kReachabilityChangedNotification
44
+ object: nil ];
45
+
32
46
self = [super init ];
33
47
return self;
34
48
}
@@ -161,7 +175,19 @@ - (void)fetchAndActivate:(id)arguments withMethodCallResult:(FLTFirebaseMethodCa
161
175
[remoteConfig fetchAndActivateWithCompletionHandler: ^(
162
176
FIRRemoteConfigFetchAndActivateStatus status, NSError *error) {
163
177
if (error != nil ) {
164
- result.error (nil , nil , nil , error);
178
+ if (error.code == 999 && _fetchAndActivateRetry == false ) {
179
+ // Note: see issue for details: https://github.com/firebase/flutterfire/issues/6196
180
+ // Only calling once as the issue noted describes how it works on second retry
181
+ // Issue appears to indicate the error code is: 999
182
+ _fetchAndActivateRetry = true ;
183
+ NSLog (@" FLTFirebaseRemoteConfigPlugin: Retrying `fetchAndActivate()` due to a cancelled "
184
+ @" request with the error code: 999." );
185
+ NSLog (@" FLTFirebaseRemoteConfigPlugin: '%@ ' host connection status: %s " , remoteHostName,
186
+ _canConnectToHost == true ? " REACHABLE" : " NOT REACHABLE" );
187
+ [self fetchAndActivate: arguments withMethodCallResult: result];
188
+ } else {
189
+ result.error (nil , nil , nil , error);
190
+ }
165
191
} else {
166
192
if (status == FIRRemoteConfigFetchAndActivateStatusSuccessFetchedFromRemote) {
167
193
result.success (@(YES ));
@@ -224,6 +250,24 @@ - (NSString *)mapValueSource:(FIRRemoteConfigSource)source {
224
250
}
225
251
}
226
252
253
+ /* !
254
+ * Called by Reachability whenever status changes.
255
+ */
256
+ - (void )reachabilityChanged : (NSNotification *)note {
257
+ // Reachability code inspired by Apple docs on checking host connectivity:
258
+ // https://developer.apple.com/library/archive/samplecode/Reachability/Listings/Reachability_APLViewController_m.html#//apple_ref/doc/uid/DTS40007324-Reachability_APLViewController_m-DontLinkElementID_7
259
+ Reachability *reachability = [note object ];
260
+
261
+ if (reachability == self.hostReachability ) {
262
+ NetworkStatus netStatus = [reachability currentReachabilityStatus ];
263
+ if (netStatus == NotReachable) {
264
+ _canConnectToHost = false ;
265
+ } else {
266
+ _canConnectToHost = true ;
267
+ }
268
+ }
269
+ }
270
+
227
271
#pragma mark - FLTFirebasePlugin
228
272
229
273
- (void )didReinitializeFirebaseCore : (void (^)(void ))completion {
0 commit comments