| 1 | 
           efrain | 
           1 | 
              | 
        
        
            | 
            | 
           2 | 
           /*
  | 
        
        
            | 
            | 
           3 | 
            * Copyright 2017 Google
  | 
        
        
            | 
            | 
           4 | 
            *
  | 
        
        
            | 
            | 
           5 | 
            * Licensed under the Apache License, Version 2.0 (the "License");
  | 
        
        
            | 
            | 
           6 | 
            * you may not use this file except in compliance with the License.
  | 
        
        
            | 
            | 
           7 | 
            * You may obtain a copy of the License at
  | 
        
        
            | 
            | 
           8 | 
            *
  | 
        
        
            | 
            | 
           9 | 
            *      http://www.apache.org/licenses/LICENSE-2.0
  | 
        
        
            | 
            | 
           10 | 
            *
  | 
        
        
            | 
            | 
           11 | 
            * Unless required by applicable law or agreed to in writing, software
  | 
        
        
            | 
            | 
           12 | 
            * distributed under the License is distributed on an "AS IS" BASIS,
  | 
        
        
            | 
            | 
           13 | 
            * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  | 
        
        
            | 
            | 
           14 | 
            * See the License for the specific language governing permissions and
  | 
        
        
            | 
            | 
           15 | 
            * limitations under the License.
  | 
        
        
            | 
            | 
           16 | 
            */
  | 
        
        
            | 
            | 
           17 | 
              | 
        
        
            | 
            | 
           18 | 
           #if !__has_feature(objc_arc)
  | 
        
        
            | 
            | 
           19 | 
           #error FIRMessagingLib should be compiled with ARC.
  | 
        
        
            | 
            | 
           20 | 
           #endif
  | 
        
        
            | 
            | 
           21 | 
              | 
        
        
            | 
            | 
           22 | 
           #import "FirebaseMessaging/Sources/Public/FirebaseMessaging/FIRMessaging.h"
  | 
        
        
            | 
            | 
           23 | 
           #import <GoogleUtilities/GULAppDelegateSwizzler.h>
  | 
        
        
            | 
            | 
           24 | 
           #import <GoogleUtilities/GULAppEnvironmentUtil.h>
  | 
        
        
            | 
            | 
           25 | 
           #import <GoogleUtilities/GULReachabilityChecker.h>
  | 
        
        
            | 
            | 
           26 | 
           #import <GoogleUtilities/GULUserDefaults.h>
  | 
        
        
            | 
            | 
           27 | 
           #import "FirebaseCore/Sources/Private/FirebaseCoreInternal.h"
  | 
        
        
            | 
            | 
           28 | 
           #import "FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h"
  | 
        
        
            | 
            | 
           29 | 
           #import "FirebaseMessaging/Sources/FIRMessagingAnalytics.h"
  | 
        
        
            | 
            | 
           30 | 
           #import "FirebaseMessaging/Sources/FIRMessagingCode.h"
  | 
        
        
            | 
            | 
           31 | 
           #import "FirebaseMessaging/Sources/FIRMessagingConstants.h"
  | 
        
        
            | 
            | 
           32 | 
           #import "FirebaseMessaging/Sources/FIRMessagingContextManagerService.h"
  | 
        
        
            | 
            | 
           33 | 
           #import "FirebaseMessaging/Sources/FIRMessagingDefines.h"
  | 
        
        
            | 
            | 
           34 | 
           #import "FirebaseMessaging/Sources/FIRMessagingLogger.h"
  | 
        
        
            | 
            | 
           35 | 
           #import "FirebaseMessaging/Sources/FIRMessagingPubSub.h"
  | 
        
        
            | 
            | 
           36 | 
           #import "FirebaseMessaging/Sources/FIRMessagingRemoteNotificationsProxy.h"
  | 
        
        
            | 
            | 
           37 | 
           #import "FirebaseMessaging/Sources/FIRMessagingRmqManager.h"
  | 
        
        
            | 
            | 
           38 | 
           #import "FirebaseMessaging/Sources/FIRMessagingSyncMessageManager.h"
  | 
        
        
            | 
            | 
           39 | 
           #import "FirebaseMessaging/Sources/FIRMessagingUtilities.h"
  | 
        
        
            | 
            | 
           40 | 
           #import "FirebaseMessaging/Sources/FIRMessaging_Private.h"
  | 
        
        
            | 
            | 
           41 | 
           #import "FirebaseMessaging/Sources/Interop/FIRMessagingInterop.h"
  | 
        
        
            | 
            | 
           42 | 
           #import "FirebaseMessaging/Sources/NSError+FIRMessaging.h"
  | 
        
        
            | 
            | 
           43 | 
           #import "FirebaseMessaging/Sources/Public/FirebaseMessaging/FIRMessagingExtensionHelper.h"
  | 
        
        
            | 
            | 
           44 | 
           #import "FirebaseMessaging/Sources/Token/FIRMessagingAuthService.h"
  | 
        
        
            | 
            | 
           45 | 
           #import "FirebaseMessaging/Sources/Token/FIRMessagingTokenInfo.h"
  | 
        
        
            | 
            | 
           46 | 
           #import "FirebaseMessaging/Sources/Token/FIRMessagingTokenManager.h"
  | 
        
        
            | 
            | 
           47 | 
           #import "Interop/Analytics/Public/FIRAnalyticsInterop.h"
  | 
        
        
            | 
            | 
           48 | 
              | 
        
        
            | 
            | 
           49 | 
           static NSString *const kFIRMessagingMessageViaAPNSRootKey = @"aps";
  | 
        
        
            | 
            | 
           50 | 
           static NSString *const kFIRMessagingReachabilityHostname = @"www.google.com";
  | 
        
        
            | 
            | 
           51 | 
              | 
        
        
            | 
            | 
           52 | 
           #if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
  | 
        
        
            | 
            | 
           53 | 
           const NSNotificationName FIRMessagingRegistrationTokenRefreshedNotification =
  | 
        
        
            | 
            | 
           54 | 
               @"com.firebase.messaging.notif.fcm-token-refreshed";
  | 
        
        
            | 
            | 
           55 | 
           #else
  | 
        
        
            | 
            | 
           56 | 
           NSString *const FIRMessagingRegistrationTokenRefreshedNotification =
  | 
        
        
            | 
            | 
           57 | 
               @"com.firebase.messaging.notif.fcm-token-refreshed";
  | 
        
        
            | 
            | 
           58 | 
           #endif  // defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
  | 
        
        
            | 
            | 
           59 | 
              | 
        
        
            | 
            | 
           60 | 
           NSString *const kFIRMessagingUserDefaultsKeyAutoInitEnabled =
  | 
        
        
            | 
            | 
           61 | 
               @"com.firebase.messaging.auto-init.enabled";  // Auto Init Enabled key stored in NSUserDefaults
  | 
        
        
            | 
            | 
           62 | 
              | 
        
        
            | 
            | 
           63 | 
           NSString *const kFIRMessagingPlistAutoInitEnabled =
  | 
        
        
            | 
            | 
           64 | 
               @"FirebaseMessagingAutoInitEnabled";  // Auto Init Enabled key stored in Info.plist
  | 
        
        
            | 
            | 
           65 | 
              | 
        
        
            | 
            | 
           66 | 
           const BOOL FIRMessagingIsAPNSSyncMessage(NSDictionary *message) {
  | 
        
        
            | 
            | 
           67 | 
             if ([message[kFIRMessagingMessageViaAPNSRootKey] isKindOfClass:[NSDictionary class]]) {
  | 
        
        
            | 
            | 
           68 | 
               NSDictionary *aps = message[kFIRMessagingMessageViaAPNSRootKey];
  | 
        
        
            | 
            | 
           69 | 
               if (aps && [aps isKindOfClass:[NSDictionary class]]) {
  | 
        
        
            | 
            | 
           70 | 
                 return [aps[kFIRMessagingMessageAPNSContentAvailableKey] boolValue];
  | 
        
        
            | 
            | 
           71 | 
               }
  | 
        
        
            | 
            | 
           72 | 
             }
  | 
        
        
            | 
            | 
           73 | 
             return NO;
  | 
        
        
            | 
            | 
           74 | 
           }
  | 
        
        
            | 
            | 
           75 | 
              | 
        
        
            | 
            | 
           76 | 
           BOOL FIRMessagingIsContextManagerMessage(NSDictionary *message) {
  | 
        
        
            | 
            | 
           77 | 
             return [FIRMessagingContextManagerService isContextManagerMessage:message];
  | 
        
        
            | 
            | 
           78 | 
           }
  | 
        
        
            | 
            | 
           79 | 
              | 
        
        
            | 
            | 
           80 | 
           @interface FIRMessagingMessageInfo ()
  | 
        
        
            | 
            | 
           81 | 
              | 
        
        
            | 
            | 
           82 | 
           @property(nonatomic, readwrite, assign) FIRMessagingMessageStatus status;
  | 
        
        
            | 
            | 
           83 | 
              | 
        
        
            | 
            | 
           84 | 
           @end
  | 
        
        
            | 
            | 
           85 | 
              | 
        
        
            | 
            | 
           86 | 
           @implementation FIRMessagingMessageInfo
  | 
        
        
            | 
            | 
           87 | 
              | 
        
        
            | 
            | 
           88 | 
           - (instancetype)init {
  | 
        
        
            | 
            | 
           89 | 
             FIRMessagingInvalidateInitializer();
  | 
        
        
            | 
            | 
           90 | 
           }
  | 
        
        
            | 
            | 
           91 | 
              | 
        
        
            | 
            | 
           92 | 
           - (instancetype)initWithStatus:(FIRMessagingMessageStatus)status {
  | 
        
        
            | 
            | 
           93 | 
             self = [super init];
  | 
        
        
            | 
            | 
           94 | 
             if (self) {
  | 
        
        
            | 
            | 
           95 | 
               _status = status;
  | 
        
        
            | 
            | 
           96 | 
             }
  | 
        
        
            | 
            | 
           97 | 
             return self;
  | 
        
        
            | 
            | 
           98 | 
           }
  | 
        
        
            | 
            | 
           99 | 
              | 
        
        
            | 
            | 
           100 | 
           @end
  | 
        
        
            | 
            | 
           101 | 
              | 
        
        
            | 
            | 
           102 | 
           @interface FIRMessaging () <GULReachabilityDelegate>
  | 
        
        
            | 
            | 
           103 | 
              | 
        
        
            | 
            | 
           104 | 
           // FIRApp properties
  | 
        
        
            | 
            | 
           105 | 
           @property(nonatomic, readwrite, strong) NSData *apnsTokenData;
  | 
        
        
            | 
            | 
           106 | 
           @property(nonatomic, readwrite, strong) FIRMessagingClient *client;
  | 
        
        
            | 
            | 
           107 | 
           @property(nonatomic, readwrite, strong) GULReachabilityChecker *reachability;
  | 
        
        
            | 
            | 
           108 | 
           @property(nonatomic, readwrite, strong) FIRMessagingPubSub *pubsub;
  | 
        
        
            | 
            | 
           109 | 
           @property(nonatomic, readwrite, strong) FIRMessagingRmqManager *rmq2Manager;
  | 
        
        
            | 
            | 
           110 | 
           @property(nonatomic, readwrite, strong) FIRMessagingSyncMessageManager *syncMessageManager;
  | 
        
        
            | 
            | 
           111 | 
           @property(nonatomic, readwrite, strong) GULUserDefaults *messagingUserDefaults;
  | 
        
        
            | 
            | 
           112 | 
           @property(nonatomic, readwrite, strong) FIRInstallations *installations;
  | 
        
        
            | 
            | 
           113 | 
           @property(nonatomic, readwrite, strong) FIRMessagingTokenManager *tokenManager;
  | 
        
        
            | 
            | 
           114 | 
              | 
        
        
            | 
            | 
           115 | 
           /// Message ID's logged for analytics. This prevents us from logging the same message twice
  | 
        
        
            | 
            | 
           116 | 
           /// which can happen if the user inadvertently calls `appDidReceiveMessage` along with us
  | 
        
        
            | 
            | 
           117 | 
           /// calling it implicitly during swizzling.
  | 
        
        
            | 
            | 
           118 | 
           @property(nonatomic, readwrite, strong) NSMutableSet *loggedMessageIDs;
  | 
        
        
            | 
            | 
           119 | 
           @property(nonatomic, readwrite, strong) id<FIRAnalyticsInterop> _Nullable analytics;
  | 
        
        
            | 
            | 
           120 | 
              | 
        
        
            | 
            | 
           121 | 
           @end
  | 
        
        
            | 
            | 
           122 | 
              | 
        
        
            | 
            | 
           123 | 
           @interface FIRMessaging () <FIRMessagingInterop, FIRLibrary>
  | 
        
        
            | 
            | 
           124 | 
           @end
  | 
        
        
            | 
            | 
           125 | 
              | 
        
        
            | 
            | 
           126 | 
           @implementation FIRMessaging
  | 
        
        
            | 
            | 
           127 | 
              | 
        
        
            | 
            | 
           128 | 
           + (FIRMessaging *)messaging {
  | 
        
        
            | 
            | 
           129 | 
             FIRApp *defaultApp = [FIRApp defaultApp];  // Missing configure will be logged here.
  | 
        
        
            | 
            | 
           130 | 
             id<FIRMessagingInterop> instance = FIR_COMPONENT(FIRMessagingInterop, defaultApp.container);
  | 
        
        
            | 
            | 
           131 | 
              | 
        
        
            | 
            | 
           132 | 
             // We know the instance coming from the container is a FIRMessaging instance, cast it and move on.
  | 
        
        
            | 
            | 
           133 | 
             return (FIRMessaging *)instance;
  | 
        
        
            | 
            | 
           134 | 
           }
  | 
        
        
            | 
            | 
           135 | 
              | 
        
        
            | 
            | 
           136 | 
           + (FIRMessagingExtensionHelper *)extensionHelper {
  | 
        
        
            | 
            | 
           137 | 
             static dispatch_once_t once;
  | 
        
        
            | 
            | 
           138 | 
             static FIRMessagingExtensionHelper *extensionHelper;
  | 
        
        
            | 
            | 
           139 | 
             dispatch_once(&once, ^{
  | 
        
        
            | 
            | 
           140 | 
               extensionHelper = [[FIRMessagingExtensionHelper alloc] init];
  | 
        
        
            | 
            | 
           141 | 
             });
  | 
        
        
            | 
            | 
           142 | 
             return extensionHelper;
  | 
        
        
            | 
            | 
           143 | 
           }
  | 
        
        
            | 
            | 
           144 | 
           #pragma clang diagnostic push
  | 
        
        
            | 
            | 
           145 | 
           #pragma clang diagnostic ignored "-Wdeprecated-declarations"
  | 
        
        
            | 
            | 
           146 | 
           - (instancetype)initWithAnalytics:(nullable id<FIRAnalyticsInterop>)analytics
  | 
        
        
            | 
            | 
           147 | 
                            withUserDefaults:(GULUserDefaults *)defaults {
  | 
        
        
            | 
            | 
           148 | 
           #pragma clang diagnostic pop
  | 
        
        
            | 
            | 
           149 | 
             self = [super init];
  | 
        
        
            | 
            | 
           150 | 
             if (self != nil) {
  | 
        
        
            | 
            | 
           151 | 
               _loggedMessageIDs = [NSMutableSet set];
  | 
        
        
            | 
            | 
           152 | 
               _messagingUserDefaults = defaults;
  | 
        
        
            | 
            | 
           153 | 
               _analytics = analytics;
  | 
        
        
            | 
            | 
           154 | 
             }
  | 
        
        
            | 
            | 
           155 | 
             return self;
  | 
        
        
            | 
            | 
           156 | 
           }
  | 
        
        
            | 
            | 
           157 | 
              | 
        
        
            | 
            | 
           158 | 
           - (void)dealloc {
  | 
        
        
            | 
            | 
           159 | 
             [self.reachability stop];
  | 
        
        
            | 
            | 
           160 | 
             [[NSNotificationCenter defaultCenter] removeObserver:self];
  | 
        
        
            | 
            | 
           161 | 
             [self teardown];
  | 
        
        
            | 
            | 
           162 | 
           }
  | 
        
        
            | 
            | 
           163 | 
              | 
        
        
            | 
            | 
           164 | 
           #pragma mark - Config
  | 
        
        
            | 
            | 
           165 | 
              | 
        
        
            | 
            | 
           166 | 
           + (void)load {
  | 
        
        
            | 
            | 
           167 | 
             [FIRApp registerInternalLibrary:(Class<FIRLibrary>)self withName:@"fire-fcm"];
  | 
        
        
            | 
            | 
           168 | 
           }
  | 
        
        
            | 
            | 
           169 | 
              | 
        
        
            | 
            | 
           170 | 
           + (nonnull NSArray<FIRComponent *> *)componentsToRegister {
  | 
        
        
            | 
            | 
           171 | 
             FIRDependency *analyticsDep = [FIRDependency dependencyWithProtocol:@protocol(FIRAnalyticsInterop)
  | 
        
        
            | 
            | 
           172 | 
                                                                      isRequired:NO];
  | 
        
        
            | 
            | 
           173 | 
             FIRComponentCreationBlock creationBlock =
  | 
        
        
            | 
            | 
           174 | 
                 ^id _Nullable(FIRComponentContainer *container, BOOL *isCacheable) {
  | 
        
        
            | 
            | 
           175 | 
               if (!container.app.isDefaultApp) {
  | 
        
        
            | 
            | 
           176 | 
                 // Only start for the default FIRApp.
  | 
        
        
            | 
            | 
           177 | 
                 FIRMessagingLoggerDebug(kFIRMessagingMessageCodeFIRApp001,
  | 
        
        
            | 
            | 
           178 | 
                                         @"Firebase Messaging only works with the default app.");
  | 
        
        
            | 
            | 
           179 | 
                 return nil;
  | 
        
        
            | 
            | 
           180 | 
               }
  | 
        
        
            | 
            | 
           181 | 
              | 
        
        
            | 
            | 
           182 | 
               // Ensure it's cached so it returns the same instance every time messaging is called.
  | 
        
        
            | 
            | 
           183 | 
               *isCacheable = YES;
  | 
        
        
            | 
            | 
           184 | 
               id<FIRAnalyticsInterop> analytics = FIR_COMPONENT(FIRAnalyticsInterop, container);
  | 
        
        
            | 
            | 
           185 | 
           #pragma clang diagnostic push
  | 
        
        
            | 
            | 
           186 | 
           #pragma clang diagnostic ignored "-Wdeprecated-declarations"
  | 
        
        
            | 
            | 
           187 | 
               FIRMessaging *messaging =
  | 
        
        
            | 
            | 
           188 | 
                   [[FIRMessaging alloc] initWithAnalytics:analytics
  | 
        
        
            | 
            | 
           189 | 
                                          withUserDefaults:[GULUserDefaults standardUserDefaults]];
  | 
        
        
            | 
            | 
           190 | 
           #pragma clang diagnostic pop
  | 
        
        
            | 
            | 
           191 | 
               [messaging start];
  | 
        
        
            | 
            | 
           192 | 
               [messaging configureMessagingWithOptions:container.app.options];
  | 
        
        
            | 
            | 
           193 | 
              | 
        
        
            | 
            | 
           194 | 
               [messaging configureNotificationSwizzlingIfEnabled];
  | 
        
        
            | 
            | 
           195 | 
               return messaging;
  | 
        
        
            | 
            | 
           196 | 
             };
  | 
        
        
            | 
            | 
           197 | 
             FIRComponent *messagingProvider =
  | 
        
        
            | 
            | 
           198 | 
                 [FIRComponent componentWithProtocol:@protocol(FIRMessagingInterop)
  | 
        
        
            | 
            | 
           199 | 
                                 instantiationTiming:FIRInstantiationTimingEagerInDefaultApp
  | 
        
        
            | 
            | 
           200 | 
                                        dependencies:@[ analyticsDep ]
  | 
        
        
            | 
            | 
           201 | 
                                       creationBlock:creationBlock];
  | 
        
        
            | 
            | 
           202 | 
              | 
        
        
            | 
            | 
           203 | 
             return @[ messagingProvider ];
  | 
        
        
            | 
            | 
           204 | 
           }
  | 
        
        
            | 
            | 
           205 | 
              | 
        
        
            | 
            | 
           206 | 
           - (void)configureMessagingWithOptions:(FIROptions *)options {
  | 
        
        
            | 
            | 
           207 | 
             NSString *GCMSenderID = options.GCMSenderID;
  | 
        
        
            | 
            | 
           208 | 
             if (!GCMSenderID.length) {
  | 
        
        
            | 
            | 
           209 | 
               FIRMessagingLoggerError(kFIRMessagingMessageCodeFIRApp000,
  | 
        
        
            | 
            | 
           210 | 
                                       @"Firebase not set up correctly, nil or empty senderID.");
  | 
        
        
            | 
            | 
           211 | 
               [NSException raise:kFIRMessagingDomain
  | 
        
        
            | 
            | 
           212 | 
                           format:@"Could not configure Firebase Messaging. GCMSenderID must not be nil or "
  | 
        
        
            | 
            | 
           213 | 
                                  @"empty."];
  | 
        
        
            | 
            | 
           214 | 
             }
  | 
        
        
            | 
            | 
           215 | 
              | 
        
        
            | 
            | 
           216 | 
             self.tokenManager.fcmSenderID = GCMSenderID;
  | 
        
        
            | 
            | 
           217 | 
             self.tokenManager.firebaseAppID = options.googleAppID;
  | 
        
        
            | 
            | 
           218 | 
              | 
        
        
            | 
            | 
           219 | 
             // FCM generates a FCM token during app start for sending push notification to device.
  | 
        
        
            | 
            | 
           220 | 
             // This is not needed for app extension except for watch.
  | 
        
        
            | 
            | 
           221 | 
           #if TARGET_OS_WATCH
  | 
        
        
            | 
            | 
           222 | 
             [self didCompleteConfigure];
  | 
        
        
            | 
            | 
           223 | 
           #else
  | 
        
        
            | 
            | 
           224 | 
             if (![GULAppEnvironmentUtil isAppExtension]) {
  | 
        
        
            | 
            | 
           225 | 
               [self didCompleteConfigure];
  | 
        
        
            | 
            | 
           226 | 
             }
  | 
        
        
            | 
            | 
           227 | 
           #endif
  | 
        
        
            | 
            | 
           228 | 
           }
  | 
        
        
            | 
            | 
           229 | 
              | 
        
        
            | 
            | 
           230 | 
           - (void)didCompleteConfigure {
  | 
        
        
            | 
            | 
           231 | 
             NSString *cachedToken =
  | 
        
        
            | 
            | 
           232 | 
                 [self.tokenManager cachedTokenInfoWithAuthorizedEntity:self.tokenManager.fcmSenderID
  | 
        
        
            | 
            | 
           233 | 
                                                                  scope:kFIRMessagingDefaultTokenScope]
  | 
        
        
            | 
            | 
           234 | 
                     .token;
  | 
        
        
            | 
            | 
           235 | 
             // When there is a cached token, do the token refresh.
  | 
        
        
            | 
            | 
           236 | 
             if (cachedToken) {
  | 
        
        
            | 
            | 
           237 | 
               // Clean up expired tokens by checking the token refresh policy.
  | 
        
        
            | 
            | 
           238 | 
               [self.installations installationIDWithCompletion:^(NSString *_Nullable identifier,
  | 
        
        
            | 
            | 
           239 | 
                                                                  NSError *_Nullable error) {
  | 
        
        
            | 
            | 
           240 | 
                 if ([self.tokenManager checkTokenRefreshPolicyWithIID:identifier]) {
  | 
        
        
            | 
            | 
           241 | 
                   // Default token is expired, fetch default token from server.
  | 
        
        
            | 
            | 
           242 | 
                   [self retrieveFCMTokenForSenderID:self.tokenManager.fcmSenderID
  | 
        
        
            | 
            | 
           243 | 
                                          completion:^(NSString *_Nullable FCMToken, NSError *_Nullable error){
  | 
        
        
            | 
            | 
           244 | 
                                          }];
  | 
        
        
            | 
            | 
           245 | 
                 }
  | 
        
        
            | 
            | 
           246 | 
                 // Set the default FCM token, there's an issue that FIRApp configure
  | 
        
        
            | 
            | 
           247 | 
                 // happens before developers able to set the delegate
  | 
        
        
            | 
            | 
           248 | 
                 // Hence first token set must be happen here after listener is set
  | 
        
        
            | 
            | 
           249 | 
                 // TODO(chliangGoogle) Need to investigate better solution.
  | 
        
        
            | 
            | 
           250 | 
                 [self updateDefaultFCMToken:self.FCMToken];
  | 
        
        
            | 
            | 
           251 | 
               }];
  | 
        
        
            | 
            | 
           252 | 
             } else if (self.isAutoInitEnabled) {
  | 
        
        
            | 
            | 
           253 | 
               // When there is no cached token, must check auto init is enabled.
  | 
        
        
            | 
            | 
           254 | 
               // If it's disabled, don't initiate token generation/refresh.
  | 
        
        
            | 
            | 
           255 | 
               // If no cache token and auto init is enabled, fetch a token from server.
  | 
        
        
            | 
            | 
           256 | 
               [self retrieveFCMTokenForSenderID:self.tokenManager.fcmSenderID
  | 
        
        
            | 
            | 
           257 | 
                                      completion:^(NSString *_Nullable FCMToken, NSError *_Nullable error){
  | 
        
        
            | 
            | 
           258 | 
                                      }];
  | 
        
        
            | 
            | 
           259 | 
             }
  | 
        
        
            | 
            | 
           260 | 
           }
  | 
        
        
            | 
            | 
           261 | 
              | 
        
        
            | 
            | 
           262 | 
           - (void)configureNotificationSwizzlingIfEnabled {
  | 
        
        
            | 
            | 
           263 | 
             // Swizzle remote-notification-related methods (app delegate and UNUserNotificationCenter)
  | 
        
        
            | 
            | 
           264 | 
             if ([FIRMessagingRemoteNotificationsProxy canSwizzleMethods]) {
  | 
        
        
            | 
            | 
           265 | 
               NSString *docsURLString = @"https://firebase.google.com/docs/cloud-messaging/ios/client"
  | 
        
        
            | 
            | 
           266 | 
                                         @"#method_swizzling_in_firebase_messaging";
  | 
        
        
            | 
            | 
           267 | 
               FIRMessagingLoggerNotice(kFIRMessagingMessageCodeFIRApp000,
  | 
        
        
            | 
            | 
           268 | 
                                        @"FIRMessaging Remote Notifications proxy enabled, will swizzle "
  | 
        
        
            | 
            | 
           269 | 
                                        @"remote notification receiver handlers. If you'd prefer to manually "
  | 
        
        
            | 
            | 
           270 | 
                                        @"integrate Firebase Messaging, add \"%@\" to your Info.plist, "
  | 
        
        
            | 
            | 
           271 | 
                                        @"and set it to NO. Follow the instructions at:\n%@\nto ensure "
  | 
        
        
            | 
            | 
           272 | 
                                        @"proper integration.",
  | 
        
        
            | 
            | 
           273 | 
                                        kFIRMessagingRemoteNotificationsProxyEnabledInfoPlistKey,
  | 
        
        
            | 
            | 
           274 | 
                                        docsURLString);
  | 
        
        
            | 
            | 
           275 | 
               [[FIRMessagingRemoteNotificationsProxy sharedProxy] swizzleMethodsIfPossible];
  | 
        
        
            | 
            | 
           276 | 
             }
  | 
        
        
            | 
            | 
           277 | 
           }
  | 
        
        
            | 
            | 
           278 | 
              | 
        
        
            | 
            | 
           279 | 
           - (void)start {
  | 
        
        
            | 
            | 
           280 | 
             [self setupFileManagerSubDirectory];
  | 
        
        
            | 
            | 
           281 | 
             [self setupNotificationListeners];
  | 
        
        
            | 
            | 
           282 | 
              | 
        
        
            | 
            | 
           283 | 
             self.tokenManager = [[FIRMessagingTokenManager alloc] init];
  | 
        
        
            | 
            | 
           284 | 
             self.installations = [FIRInstallations installations];
  | 
        
        
            | 
            | 
           285 | 
             [self setupTopics];
  | 
        
        
            | 
            | 
           286 | 
              | 
        
        
            | 
            | 
           287 | 
             // Print the library version for logging.
  | 
        
        
            | 
            | 
           288 | 
             NSString *currentLibraryVersion = FIRFirebaseVersion();
  | 
        
        
            | 
            | 
           289 | 
             FIRMessagingLoggerInfo(kFIRMessagingMessageCodeMessagingPrintLibraryVersion,
  | 
        
        
            | 
            | 
           290 | 
                                    @"FIRMessaging library version %@", currentLibraryVersion);
  | 
        
        
            | 
            | 
           291 | 
              | 
        
        
            | 
            | 
           292 | 
             NSString *hostname = kFIRMessagingReachabilityHostname;
  | 
        
        
            | 
            | 
           293 | 
             self.reachability = [[GULReachabilityChecker alloc] initWithReachabilityDelegate:self
  | 
        
        
            | 
            | 
           294 | 
                                                                                     withHost:hostname];
  | 
        
        
            | 
            | 
           295 | 
             [self.reachability start];
  | 
        
        
            | 
            | 
           296 | 
              | 
        
        
            | 
            | 
           297 | 
             // setup FIRMessaging objects
  | 
        
        
            | 
            | 
           298 | 
             [self setupRmqManager];
  | 
        
        
            | 
            | 
           299 | 
             [self setupSyncMessageManager];
  | 
        
        
            | 
            | 
           300 | 
           }
  | 
        
        
            | 
            | 
           301 | 
              | 
        
        
            | 
            | 
           302 | 
           - (void)setupFileManagerSubDirectory {
  | 
        
        
            | 
            | 
           303 | 
             if (![[self class] hasSubDirectory:kFIRMessagingSubDirectoryName]) {
  | 
        
        
            | 
            | 
           304 | 
               [[self class] createSubDirectory:kFIRMessagingSubDirectoryName];
  | 
        
        
            | 
            | 
           305 | 
             }
  | 
        
        
            | 
            | 
           306 | 
             if (![[self class] hasSubDirectory:kFIRMessagingInstanceIDSubDirectoryName]) {
  | 
        
        
            | 
            | 
           307 | 
               [[self class] createSubDirectory:kFIRMessagingInstanceIDSubDirectoryName];
  | 
        
        
            | 
            | 
           308 | 
             }
  | 
        
        
            | 
            | 
           309 | 
           }
  | 
        
        
            | 
            | 
           310 | 
              | 
        
        
            | 
            | 
           311 | 
           - (void)setupNotificationListeners {
  | 
        
        
            | 
            | 
           312 | 
             // To prevent multiple notifications remove self as observer for all events.
  | 
        
        
            | 
            | 
           313 | 
             NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
  | 
        
        
            | 
            | 
           314 | 
             [center removeObserver:self];
  | 
        
        
            | 
            | 
           315 | 
             [center addObserver:self
  | 
        
        
            | 
            | 
           316 | 
                        selector:@selector(defaultFCMTokenWasRefreshed:)
  | 
        
        
            | 
            | 
           317 | 
                            name:kFIRMessagingRegistrationTokenRefreshNotification
  | 
        
        
            | 
            | 
           318 | 
                          object:nil];
  | 
        
        
            | 
            | 
           319 | 
           }
  | 
        
        
            | 
            | 
           320 | 
              | 
        
        
            | 
            | 
           321 | 
           - (void)setupRmqManager {
  | 
        
        
            | 
            | 
           322 | 
             self.rmq2Manager = [[FIRMessagingRmqManager alloc] initWithDatabaseName:@"rmq2"];
  | 
        
        
            | 
            | 
           323 | 
             [self.rmq2Manager loadRmqId];
  | 
        
        
            | 
            | 
           324 | 
           }
  | 
        
        
            | 
            | 
           325 | 
              | 
        
        
            | 
            | 
           326 | 
           - (void)setupTopics {
  | 
        
        
            | 
            | 
           327 | 
             self.pubsub = [[FIRMessagingPubSub alloc] initWithTokenManager:self.tokenManager];
  | 
        
        
            | 
            | 
           328 | 
           }
  | 
        
        
            | 
            | 
           329 | 
              | 
        
        
            | 
            | 
           330 | 
           - (void)setupSyncMessageManager {
  | 
        
        
            | 
            | 
           331 | 
             self.syncMessageManager =
  | 
        
        
            | 
            | 
           332 | 
                 [[FIRMessagingSyncMessageManager alloc] initWithRmqManager:self.rmq2Manager];
  | 
        
        
            | 
            | 
           333 | 
             [self.syncMessageManager removeExpiredSyncMessages];
  | 
        
        
            | 
            | 
           334 | 
           }
  | 
        
        
            | 
            | 
           335 | 
              | 
        
        
            | 
            | 
           336 | 
           - (void)teardown {
  | 
        
        
            | 
            | 
           337 | 
             self.pubsub = nil;
  | 
        
        
            | 
            | 
           338 | 
             self.syncMessageManager = nil;
  | 
        
        
            | 
            | 
           339 | 
             self.rmq2Manager = nil;
  | 
        
        
            | 
            | 
           340 | 
             FIRMessagingLoggerDebug(kFIRMessagingMessageCodeMessaging001, @"Did successfully teardown");
  | 
        
        
            | 
            | 
           341 | 
           }
  | 
        
        
            | 
            | 
           342 | 
              | 
        
        
            | 
            | 
           343 | 
           #pragma mark - Messages
  | 
        
        
            | 
            | 
           344 | 
              | 
        
        
            | 
            | 
           345 | 
           - (FIRMessagingMessageInfo *)appDidReceiveMessage:(NSDictionary *)message {
  | 
        
        
            | 
            | 
           346 | 
             if (!message.count) {
  | 
        
        
            | 
            | 
           347 | 
               return [[FIRMessagingMessageInfo alloc] initWithStatus:FIRMessagingMessageStatusUnknown];
  | 
        
        
            | 
            | 
           348 | 
             }
  | 
        
        
            | 
            | 
           349 | 
              | 
        
        
            | 
            | 
           350 | 
             // For downstream messages that go via MCS we should strip out this key before sending
  | 
        
        
            | 
            | 
           351 | 
             // the message to the device.
  | 
        
        
            | 
            | 
           352 | 
             BOOL isOldMessage = NO;
  | 
        
        
            | 
            | 
           353 | 
             NSString *messageID = message[kFIRMessagingMessageIDKey];
  | 
        
        
            | 
            | 
           354 | 
             if (messageID.length) {
  | 
        
        
            | 
            | 
           355 | 
               [self.rmq2Manager saveS2dMessageWithRmqId:messageID];
  | 
        
        
            | 
            | 
           356 | 
              | 
        
        
            | 
            | 
           357 | 
               BOOL isSyncMessage = FIRMessagingIsAPNSSyncMessage(message);
  | 
        
        
            | 
            | 
           358 | 
               if (isSyncMessage) {
  | 
        
        
            | 
            | 
           359 | 
                 isOldMessage = [self.syncMessageManager didReceiveAPNSSyncMessage:message];
  | 
        
        
            | 
            | 
           360 | 
               }
  | 
        
        
            | 
            | 
           361 | 
              | 
        
        
            | 
            | 
           362 | 
               // Prevent duplicates by keeping a cache of all the logged messages during each session.
  | 
        
        
            | 
            | 
           363 | 
               // The duplicates only happen when the 3P app calls `appDidReceiveMessage:` along with
  | 
        
        
            | 
            | 
           364 | 
               // us swizzling their implementation to call the same method implicitly.
  | 
        
        
            | 
            | 
           365 | 
               // We need to rule out the contextual message because it shares the same message ID
  | 
        
        
            | 
            | 
           366 | 
               // as the local notification it will schedule. And because it is also a APNSSync message
  | 
        
        
            | 
            | 
           367 | 
               // its duplication is already checked previously.
  | 
        
        
            | 
            | 
           368 | 
               if (!isOldMessage && !FIRMessagingIsContextManagerMessage(message)) {
  | 
        
        
            | 
            | 
           369 | 
                 isOldMessage = [self.loggedMessageIDs containsObject:messageID];
  | 
        
        
            | 
            | 
           370 | 
                 if (!isOldMessage) {
  | 
        
        
            | 
            | 
           371 | 
                   [self.loggedMessageIDs addObject:messageID];
  | 
        
        
            | 
            | 
           372 | 
                 }
  | 
        
        
            | 
            | 
           373 | 
               }
  | 
        
        
            | 
            | 
           374 | 
             }
  | 
        
        
            | 
            | 
           375 | 
              | 
        
        
            | 
            | 
           376 | 
             if (!isOldMessage) {
  | 
        
        
            | 
            | 
           377 | 
               [FIRMessagingAnalytics logMessage:message toAnalytics:_analytics];
  | 
        
        
            | 
            | 
           378 | 
               [self handleContextManagerMessage:message];
  | 
        
        
            | 
            | 
           379 | 
               [self handleIncomingLinkIfNeededFromMessage:message];
  | 
        
        
            | 
            | 
           380 | 
             }
  | 
        
        
            | 
            | 
           381 | 
             return [[FIRMessagingMessageInfo alloc] initWithStatus:FIRMessagingMessageStatusNew];
  | 
        
        
            | 
            | 
           382 | 
           }
  | 
        
        
            | 
            | 
           383 | 
              | 
        
        
            | 
            | 
           384 | 
           - (BOOL)handleContextManagerMessage:(NSDictionary *)message {
  | 
        
        
            | 
            | 
           385 | 
             if (FIRMessagingIsContextManagerMessage(message)) {
  | 
        
        
            | 
            | 
           386 | 
               return [FIRMessagingContextManagerService handleContextManagerMessage:message];
  | 
        
        
            | 
            | 
           387 | 
             }
  | 
        
        
            | 
            | 
           388 | 
             return NO;
  | 
        
        
            | 
            | 
           389 | 
           }
  | 
        
        
            | 
            | 
           390 | 
              | 
        
        
            | 
            | 
           391 | 
           - (void)handleIncomingLinkIfNeededFromMessage:(NSDictionary *)message {
  | 
        
        
            | 
            | 
           392 | 
           #if TARGET_OS_IOS || TARGET_OS_TV
  | 
        
        
            | 
            | 
           393 | 
             NSURL *url = [self linkURLFromMessage:message];
  | 
        
        
            | 
            | 
           394 | 
             if (url == nil) {
  | 
        
        
            | 
            | 
           395 | 
               return;
  | 
        
        
            | 
            | 
           396 | 
             }
  | 
        
        
            | 
            | 
           397 | 
             if (![NSThread isMainThread]) {
  | 
        
        
            | 
            | 
           398 | 
               dispatch_async(dispatch_get_main_queue(), ^{
  | 
        
        
            | 
            | 
           399 | 
                 [self handleIncomingLinkIfNeededFromMessage:message];
  | 
        
        
            | 
            | 
           400 | 
               });
  | 
        
        
            | 
            | 
           401 | 
               return;
  | 
        
        
            | 
            | 
           402 | 
             }
  | 
        
        
            | 
            | 
           403 | 
             UIApplication *application = [GULAppDelegateSwizzler sharedApplication];
  | 
        
        
            | 
            | 
           404 | 
             if (!application) {
  | 
        
        
            | 
            | 
           405 | 
               return;
  | 
        
        
            | 
            | 
           406 | 
             }
  | 
        
        
            | 
            | 
           407 | 
             id<UIApplicationDelegate> appDelegate = application.delegate;
  | 
        
        
            | 
            | 
           408 | 
             SEL continueUserActivitySelector = @selector(application:
  | 
        
        
            | 
            | 
           409 | 
                                                 continueUserActivity:restorationHandler:);
  | 
        
        
            | 
            | 
           410 | 
              | 
        
        
            | 
            | 
           411 | 
             SEL openURLWithOptionsSelector = @selector(application:openURL:options:);
  | 
        
        
            | 
            | 
           412 | 
             SEL openURLWithSourceApplicationSelector = @selector(application:
  | 
        
        
            | 
            | 
           413 | 
                                                                      openURL:sourceApplication:annotation:);
  | 
        
        
            | 
            | 
           414 | 
           #if TARGET_OS_IOS
  | 
        
        
            | 
            | 
           415 | 
             SEL handleOpenURLSelector = @selector(application:handleOpenURL:);
  | 
        
        
            | 
            | 
           416 | 
           #endif
  | 
        
        
            | 
            | 
           417 | 
             // Due to FIRAAppDelegateProxy swizzling, this selector will most likely get chosen, whether or
  | 
        
        
            | 
            | 
           418 | 
             // not the actual application has implemented
  | 
        
        
            | 
            | 
           419 | 
             // |application:continueUserActivity:restorationHandler:|. A warning will be displayed to the user
  | 
        
        
            | 
            | 
           420 | 
             // if they haven't implemented it.
  | 
        
        
            | 
            | 
           421 | 
             if ([NSUserActivity class] != nil &&
  | 
        
        
            | 
            | 
           422 | 
                 [appDelegate respondsToSelector:continueUserActivitySelector]) {
  | 
        
        
            | 
            | 
           423 | 
               NSUserActivity *userActivity =
  | 
        
        
            | 
            | 
           424 | 
                   [[NSUserActivity alloc] initWithActivityType:NSUserActivityTypeBrowsingWeb];
  | 
        
        
            | 
            | 
           425 | 
               userActivity.webpageURL = url;
  | 
        
        
            | 
            | 
           426 | 
               [appDelegate application:application
  | 
        
        
            | 
            | 
           427 | 
                   continueUserActivity:userActivity
  | 
        
        
            | 
            | 
           428 | 
                     restorationHandler:^(NSArray *_Nullable restorableObjects){
  | 
        
        
            | 
            | 
           429 | 
                         // Do nothing, as we don't support the app calling this block
  | 
        
        
            | 
            | 
           430 | 
                     }];
  | 
        
        
            | 
            | 
           431 | 
              | 
        
        
            | 
            | 
           432 | 
             } else if ([appDelegate respondsToSelector:openURLWithOptionsSelector]) {
  | 
        
        
            | 
            | 
           433 | 
           #pragma clang diagnostic push
  | 
        
        
            | 
            | 
           434 | 
           #pragma clang diagnostic ignored "-Wunguarded-availability"
  | 
        
        
            | 
            | 
           435 | 
               [appDelegate application:application openURL:url options:@{}];
  | 
        
        
            | 
            | 
           436 | 
           #pragma clang diagnostic pop
  | 
        
        
            | 
            | 
           437 | 
               // Similarly, |application:openURL:sourceApplication:annotation:| will also always be called,
  | 
        
        
            | 
            | 
           438 | 
               // due to the default swizzling done by FIRAAppDelegateProxy in Firebase Analytics
  | 
        
        
            | 
            | 
           439 | 
             } else if ([appDelegate respondsToSelector:openURLWithSourceApplicationSelector]) {
  | 
        
        
            | 
            | 
           440 | 
           #if TARGET_OS_IOS
  | 
        
        
            | 
            | 
           441 | 
           #pragma clang diagnostic push
  | 
        
        
            | 
            | 
           442 | 
           #pragma clang diagnostic ignored "-Wdeprecated-declarations"
  | 
        
        
            | 
            | 
           443 | 
               [appDelegate application:application
  | 
        
        
            | 
            | 
           444 | 
                                openURL:url
  | 
        
        
            | 
            | 
           445 | 
                      sourceApplication:FIRMessagingAppIdentifier()
  | 
        
        
            | 
            | 
           446 | 
                             annotation:@{}];
  | 
        
        
            | 
            | 
           447 | 
           #pragma clang diagnostic pop
  | 
        
        
            | 
            | 
           448 | 
             } else if ([appDelegate respondsToSelector:handleOpenURLSelector]) {
  | 
        
        
            | 
            | 
           449 | 
           #pragma clang diagnostic push
  | 
        
        
            | 
            | 
           450 | 
           #pragma clang diagnostic ignored "-Wdeprecated-declarations"
  | 
        
        
            | 
            | 
           451 | 
               [appDelegate application:application handleOpenURL:url];
  | 
        
        
            | 
            | 
           452 | 
           #pragma clang diagnostic pop
  | 
        
        
            | 
            | 
           453 | 
           #endif
  | 
        
        
            | 
            | 
           454 | 
             }
  | 
        
        
            | 
            | 
           455 | 
           #endif
  | 
        
        
            | 
            | 
           456 | 
           }
  | 
        
        
            | 
            | 
           457 | 
              | 
        
        
            | 
            | 
           458 | 
           - (NSURL *)linkURLFromMessage:(NSDictionary *)message {
  | 
        
        
            | 
            | 
           459 | 
             NSString *urlString = message[kFIRMessagingMessageLinkKey];
  | 
        
        
            | 
            | 
           460 | 
             if (urlString == nil || ![urlString isKindOfClass:[NSString class]] || urlString.length == 0) {
  | 
        
        
            | 
            | 
           461 | 
               return nil;
  | 
        
        
            | 
            | 
           462 | 
             }
  | 
        
        
            | 
            | 
           463 | 
             NSURL *url = [NSURL URLWithString:urlString];
  | 
        
        
            | 
            | 
           464 | 
             return url;
  | 
        
        
            | 
            | 
           465 | 
           }
  | 
        
        
            | 
            | 
           466 | 
              | 
        
        
            | 
            | 
           467 | 
           #pragma mark - APNS
  | 
        
        
            | 
            | 
           468 | 
              | 
        
        
            | 
            | 
           469 | 
           - (NSData *)APNSToken {
  | 
        
        
            | 
            | 
           470 | 
             return self.apnsTokenData;
  | 
        
        
            | 
            | 
           471 | 
           }
  | 
        
        
            | 
            | 
           472 | 
              | 
        
        
            | 
            | 
           473 | 
           - (void)setAPNSToken:(NSData *)APNSToken {
  | 
        
        
            | 
            | 
           474 | 
             [self setAPNSToken:APNSToken type:FIRMessagingAPNSTokenTypeUnknown];
  | 
        
        
            | 
            | 
           475 | 
           }
  | 
        
        
            | 
            | 
           476 | 
              | 
        
        
            | 
            | 
           477 | 
           - (void)setAPNSToken:(NSData *)apnsToken type:(FIRMessagingAPNSTokenType)type {
  | 
        
        
            | 
            | 
           478 | 
             if ([apnsToken isEqual:self.apnsTokenData]) {
  | 
        
        
            | 
            | 
           479 | 
               return;
  | 
        
        
            | 
            | 
           480 | 
             }
  | 
        
        
            | 
            | 
           481 | 
             self.apnsTokenData = apnsToken;
  | 
        
        
            | 
            | 
           482 | 
              | 
        
        
            | 
            | 
           483 | 
             // Notify InstanceID that APNS Token has been set.
  | 
        
        
            | 
            | 
           484 | 
             NSDictionary *userInfo = @{kFIRMessagingAPNSTokenType : @(type)};
  | 
        
        
            | 
            | 
           485 | 
             // TODO(chliang) This is sent to InstanceID in case users are still using the deprecated SDK.
  | 
        
        
            | 
            | 
           486 | 
             // Should be safe to remove once InstanceID is removed.
  | 
        
        
            | 
            | 
           487 | 
             NSNotification *notification =
  | 
        
        
            | 
            | 
           488 | 
                 [NSNotification notificationWithName:kFIRMessagingAPNSTokenNotification
  | 
        
        
            | 
            | 
           489 | 
                                               object:[apnsToken copy]
  | 
        
        
            | 
            | 
           490 | 
                                             userInfo:userInfo];
  | 
        
        
            | 
            | 
           491 | 
             [[NSNotificationQueue defaultQueue] enqueueNotification:notification postingStyle:NSPostASAP];
  | 
        
        
            | 
            | 
           492 | 
              | 
        
        
            | 
            | 
           493 | 
             [self.tokenManager setAPNSToken:[apnsToken copy] withUserInfo:userInfo];
  | 
        
        
            | 
            | 
           494 | 
           }
  | 
        
        
            | 
            | 
           495 | 
              | 
        
        
            | 
            | 
           496 | 
           #pragma mark - FCM Token
  | 
        
        
            | 
            | 
           497 | 
              | 
        
        
            | 
            | 
           498 | 
           - (BOOL)isAutoInitEnabled {
  | 
        
        
            | 
            | 
           499 | 
             // Defer to the class method since we're just reading from regular userDefaults and we need to
  | 
        
        
            | 
            | 
           500 | 
             // read this from IID without instantiating the Messaging singleton.
  | 
        
        
            | 
            | 
           501 | 
             return [[self class] isAutoInitEnabledWithUserDefaults:_messagingUserDefaults];
  | 
        
        
            | 
            | 
           502 | 
           }
  | 
        
        
            | 
            | 
           503 | 
              | 
        
        
            | 
            | 
           504 | 
           /// Checks if Messaging auto-init is enabled in the user defaults instance passed in. This is
  | 
        
        
            | 
            | 
           505 | 
           /// exposed as a class property for IID to fetch the property without instantiating an instance of
  | 
        
        
            | 
            | 
           506 | 
           /// Messaging. Since Messaging can only be used with the default FIRApp, we can have one point of
  | 
        
        
            | 
            | 
           507 | 
           /// entry without context of which FIRApp instance is being used.
  | 
        
        
            | 
            | 
           508 | 
           /// ** THIS METHOD IS DEPENDED ON INTERNALLY BY IID USING REFLECTION. PLEASE DO NOT CHANGE THE
  | 
        
        
            | 
            | 
           509 | 
           ///  SIGNATURE, AS IT WOULD BREAK AUTOINIT FUNCTIONALITY WITHIN IID. **
  | 
        
        
            | 
            | 
           510 | 
           + (BOOL)isAutoInitEnabledWithUserDefaults:(GULUserDefaults *)userDefaults {
  | 
        
        
            | 
            | 
           511 | 
             // Check storage
  | 
        
        
            | 
            | 
           512 | 
             id isAutoInitEnabledObject =
  | 
        
        
            | 
            | 
           513 | 
                 [userDefaults objectForKey:kFIRMessagingUserDefaultsKeyAutoInitEnabled];
  | 
        
        
            | 
            | 
           514 | 
             if (isAutoInitEnabledObject) {
  | 
        
        
            | 
            | 
           515 | 
               return [isAutoInitEnabledObject boolValue];
  | 
        
        
            | 
            | 
           516 | 
             }
  | 
        
        
            | 
            | 
           517 | 
              | 
        
        
            | 
            | 
           518 | 
             // Check Info.plist
  | 
        
        
            | 
            | 
           519 | 
             isAutoInitEnabledObject =
  | 
        
        
            | 
            | 
           520 | 
                 [[NSBundle mainBundle] objectForInfoDictionaryKey:kFIRMessagingPlistAutoInitEnabled];
  | 
        
        
            | 
            | 
           521 | 
             if (isAutoInitEnabledObject) {
  | 
        
        
            | 
            | 
           522 | 
               return [isAutoInitEnabledObject boolValue];
  | 
        
        
            | 
            | 
           523 | 
             }
  | 
        
        
            | 
            | 
           524 | 
              | 
        
        
            | 
            | 
           525 | 
             // If none of above exists, we default to the global switch that comes from FIRApp.
  | 
        
        
            | 
            | 
           526 | 
             return [[FIRApp defaultApp] isDataCollectionDefaultEnabled];
  | 
        
        
            | 
            | 
           527 | 
           }
  | 
        
        
            | 
            | 
           528 | 
              | 
        
        
            | 
            | 
           529 | 
           - (void)setAutoInitEnabled:(BOOL)autoInitEnabled {
  | 
        
        
            | 
            | 
           530 | 
             BOOL isFCMAutoInitEnabled = [self isAutoInitEnabled];
  | 
        
        
            | 
            | 
           531 | 
             [_messagingUserDefaults setBool:autoInitEnabled
  | 
        
        
            | 
            | 
           532 | 
                                      forKey:kFIRMessagingUserDefaultsKeyAutoInitEnabled];
  | 
        
        
            | 
            | 
           533 | 
             [_messagingUserDefaults synchronize];
  | 
        
        
            | 
            | 
           534 | 
             if (!isFCMAutoInitEnabled && autoInitEnabled) {
  | 
        
        
            | 
            | 
           535 | 
               [self.tokenManager tokenAndRequestIfNotExist];
  | 
        
        
            | 
            | 
           536 | 
             }
  | 
        
        
            | 
            | 
           537 | 
           }
  | 
        
        
            | 
            | 
           538 | 
              | 
        
        
            | 
            | 
           539 | 
           - (NSString *)FCMToken {
  | 
        
        
            | 
            | 
           540 | 
             // Gets the current default token, and requets a new one if it doesn't exist.
  | 
        
        
            | 
            | 
           541 | 
             NSString *token = [self.tokenManager tokenAndRequestIfNotExist];
  | 
        
        
            | 
            | 
           542 | 
             return token;
  | 
        
        
            | 
            | 
           543 | 
           }
  | 
        
        
            | 
            | 
           544 | 
              | 
        
        
            | 
            | 
           545 | 
           - (void)tokenWithCompletion:(FIRMessagingFCMTokenFetchCompletion)completion {
  | 
        
        
            | 
            | 
           546 | 
             FIROptions *options = FIRApp.defaultApp.options;
  | 
        
        
            | 
            | 
           547 | 
             [self retrieveFCMTokenForSenderID:options.GCMSenderID completion:completion];
  | 
        
        
            | 
            | 
           548 | 
           }
  | 
        
        
            | 
            | 
           549 | 
           - (void)deleteTokenWithCompletion:(FIRMessagingDeleteFCMTokenCompletion)completion {
  | 
        
        
            | 
            | 
           550 | 
             FIROptions *options = FIRApp.defaultApp.options;
  | 
        
        
            | 
            | 
           551 | 
             [self deleteFCMTokenForSenderID:options.GCMSenderID completion:completion];
  | 
        
        
            | 
            | 
           552 | 
           }
  | 
        
        
            | 
            | 
           553 | 
              | 
        
        
            | 
            | 
           554 | 
           - (void)retrieveFCMTokenForSenderID:(nonnull NSString *)senderID
  | 
        
        
            | 
            | 
           555 | 
                                    completion:(nonnull FIRMessagingFCMTokenFetchCompletion)completion {
  | 
        
        
            | 
            | 
           556 | 
             if (!senderID.length) {
  | 
        
        
            | 
            | 
           557 | 
               NSString *description = @"Couldn't fetch token because a Sender ID was not supplied. A valid "
  | 
        
        
            | 
            | 
           558 | 
                                       @"Sender ID is required to fetch an FCM token";
  | 
        
        
            | 
            | 
           559 | 
               FIRMessagingLoggerError(kFIRMessagingMessageCodeSenderIDNotSuppliedForTokenFetch, @"%@",
  | 
        
        
            | 
            | 
           560 | 
                                       description);
  | 
        
        
            | 
            | 
           561 | 
               if (completion) {
  | 
        
        
            | 
            | 
           562 | 
                 NSError *error = [NSError messagingErrorWithCode:kFIRMessagingErrorCodeMissingAuthorizedEntity
  | 
        
        
            | 
            | 
           563 | 
                                                    failureReason:description];
  | 
        
        
            | 
            | 
           564 | 
                 completion(nil, error);
  | 
        
        
            | 
            | 
           565 | 
               }
  | 
        
        
            | 
            | 
           566 | 
               return;
  | 
        
        
            | 
            | 
           567 | 
             }
  | 
        
        
            | 
            | 
           568 | 
             NSDictionary *options = nil;
  | 
        
        
            | 
            | 
           569 | 
             if (self.APNSToken) {
  | 
        
        
            | 
            | 
           570 | 
               options = @{kFIRMessagingTokenOptionsAPNSKey : self.APNSToken};
  | 
        
        
            | 
            | 
           571 | 
             } else {
  | 
        
        
            | 
            | 
           572 | 
               FIRMessagingLoggerWarn(kFIRMessagingMessageCodeAPNSTokenNotAvailableDuringTokenFetch,
  | 
        
        
            | 
            | 
           573 | 
                                      @"APNS device token not set before retrieving FCM Token for Sender ID "
  | 
        
        
            | 
            | 
           574 | 
                                      @"'%@'. Notifications to this FCM Token will not be delivered over APNS."
  | 
        
        
            | 
            | 
           575 | 
                                      @"Be sure to re-retrieve the FCM token once the APNS device token is "
  | 
        
        
            | 
            | 
           576 | 
                                      @"set.",
  | 
        
        
            | 
            | 
           577 | 
                                      senderID);
  | 
        
        
            | 
            | 
           578 | 
             }
  | 
        
        
            | 
            | 
           579 | 
             [self.tokenManager
  | 
        
        
            | 
            | 
           580 | 
                 tokenWithAuthorizedEntity:senderID
  | 
        
        
            | 
            | 
           581 | 
                                     scope:kFIRMessagingDefaultTokenScope
  | 
        
        
            | 
            | 
           582 | 
                                   options:options
  | 
        
        
            | 
            | 
           583 | 
                                   handler:^(NSString *_Nullable FCMToken, NSError *_Nullable error) {
  | 
        
        
            | 
            | 
           584 | 
                                     if (completion) {
  | 
        
        
            | 
            | 
           585 | 
                                       completion(FCMToken, error);
  | 
        
        
            | 
            | 
           586 | 
                                     }
  | 
        
        
            | 
            | 
           587 | 
                                   }];
  | 
        
        
            | 
            | 
           588 | 
           }
  | 
        
        
            | 
            | 
           589 | 
              | 
        
        
            | 
            | 
           590 | 
           - (void)deleteFCMTokenForSenderID:(nonnull NSString *)senderID
  | 
        
        
            | 
            | 
           591 | 
                                  completion:(nonnull FIRMessagingDeleteFCMTokenCompletion)completion {
  | 
        
        
            | 
            | 
           592 | 
             if (!senderID.length) {
  | 
        
        
            | 
            | 
           593 | 
               NSString *description = @"Couldn't delete token because a Sender ID was not supplied. A "
  | 
        
        
            | 
            | 
           594 | 
                                       @"valid Sender ID is required to delete an FCM token";
  | 
        
        
            | 
            | 
           595 | 
               FIRMessagingLoggerError(kFIRMessagingMessageCodeSenderIDNotSuppliedForTokenDelete, @"%@",
  | 
        
        
            | 
            | 
           596 | 
                                       description);
  | 
        
        
            | 
            | 
           597 | 
               if (completion) {
  | 
        
        
            | 
            | 
           598 | 
                 NSError *error = [NSError messagingErrorWithCode:kFIRMessagingErrorCodeInvalidRequest
  | 
        
        
            | 
            | 
           599 | 
                                                    failureReason:description];
  | 
        
        
            | 
            | 
           600 | 
                 completion(error);
  | 
        
        
            | 
            | 
           601 | 
               }
  | 
        
        
            | 
            | 
           602 | 
               return;
  | 
        
        
            | 
            | 
           603 | 
             }
  | 
        
        
            | 
            | 
           604 | 
             FIRMessaging_WEAKIFY(self);
  | 
        
        
            | 
            | 
           605 | 
             [self.installations
  | 
        
        
            | 
            | 
           606 | 
                 installationIDWithCompletion:^(NSString *_Nullable identifier, NSError *_Nullable error) {
  | 
        
        
            | 
            | 
           607 | 
                   FIRMessaging_STRONGIFY(self);
  | 
        
        
            | 
            | 
           608 | 
                   if (error) {
  | 
        
        
            | 
            | 
           609 | 
                     NSError *newError = [NSError messagingErrorWithCode:kFIRMessagingErrorCodeInvalidIdentity
  | 
        
        
            | 
            | 
           610 | 
                                                           failureReason:@"Failed to get installation ID."];
  | 
        
        
            | 
            | 
           611 | 
                     completion(newError);
  | 
        
        
            | 
            | 
           612 | 
                   } else {
  | 
        
        
            | 
            | 
           613 | 
                     [self.tokenManager deleteTokenWithAuthorizedEntity:senderID
  | 
        
        
            | 
            | 
           614 | 
                                                                  scope:kFIRMessagingDefaultTokenScope
  | 
        
        
            | 
            | 
           615 | 
                                                             instanceID:identifier
  | 
        
        
            | 
            | 
           616 | 
                                                                handler:^(NSError *_Nullable error) {
  | 
        
        
            | 
            | 
           617 | 
                                                                  if (completion) {
  | 
        
        
            | 
            | 
           618 | 
                                                                    completion(error);
  | 
        
        
            | 
            | 
           619 | 
                                                                  }
  | 
        
        
            | 
            | 
           620 | 
                                                                }];
  | 
        
        
            | 
            | 
           621 | 
                   }
  | 
        
        
            | 
            | 
           622 | 
                 }];
  | 
        
        
            | 
            | 
           623 | 
           }
  | 
        
        
            | 
            | 
           624 | 
              | 
        
        
            | 
            | 
           625 | 
           - (void)deleteDataWithCompletion:(void (^)(NSError *_Nullable))completion {
  | 
        
        
            | 
            | 
           626 | 
             FIRMessaging_WEAKIFY(self);
  | 
        
        
            | 
            | 
           627 | 
             [self.tokenManager deleteWithHandler:^(NSError *error) {
  | 
        
        
            | 
            | 
           628 | 
               FIRMessaging_STRONGIFY(self);
  | 
        
        
            | 
            | 
           629 | 
               if (error) {
  | 
        
        
            | 
            | 
           630 | 
                 if (completion) {
  | 
        
        
            | 
            | 
           631 | 
                   completion(error);
  | 
        
        
            | 
            | 
           632 | 
                 }
  | 
        
        
            | 
            | 
           633 | 
                 return;
  | 
        
        
            | 
            | 
           634 | 
               }
  | 
        
        
            | 
            | 
           635 | 
               // Only request new token if FCM auto initialization is
  | 
        
        
            | 
            | 
           636 | 
               // enabled.
  | 
        
        
            | 
            | 
           637 | 
               if ([self isAutoInitEnabled]) {
  | 
        
        
            | 
            | 
           638 | 
                 // Deletion succeeds! Requesting new checkin, IID and token.
  | 
        
        
            | 
            | 
           639 | 
                 [self tokenWithCompletion:^(NSString *_Nullable token, NSError *_Nullable error) {
  | 
        
        
            | 
            | 
           640 | 
                   if (completion) {
  | 
        
        
            | 
            | 
           641 | 
                     completion(error);
  | 
        
        
            | 
            | 
           642 | 
                   }
  | 
        
        
            | 
            | 
           643 | 
                 }];
  | 
        
        
            | 
            | 
           644 | 
                 return;
  | 
        
        
            | 
            | 
           645 | 
               }
  | 
        
        
            | 
            | 
           646 | 
               if (completion) {
  | 
        
        
            | 
            | 
           647 | 
                 completion(nil);
  | 
        
        
            | 
            | 
           648 | 
               }
  | 
        
        
            | 
            | 
           649 | 
             }];
  | 
        
        
            | 
            | 
           650 | 
           }
  | 
        
        
            | 
            | 
           651 | 
              | 
        
        
            | 
            | 
           652 | 
           #pragma mark - FIRMessagingDelegate helper methods
  | 
        
        
            | 
            | 
           653 | 
           - (void)setDelegate:(id<FIRMessagingDelegate>)delegate {
  | 
        
        
            | 
            | 
           654 | 
             _delegate = delegate;
  | 
        
        
            | 
            | 
           655 | 
             [self validateDelegateConformsToTokenAvailabilityMethods];
  | 
        
        
            | 
            | 
           656 | 
           }
  | 
        
        
            | 
            | 
           657 | 
              | 
        
        
            | 
            | 
           658 | 
           // Check if the delegate conforms to |didReceiveRegistrationToken:|
  | 
        
        
            | 
            | 
           659 | 
           // and display a warning to the developer if not.
  | 
        
        
            | 
            | 
           660 | 
           // NOTE: Once |didReceiveRegistrationToken:| can be made a required method, this
  | 
        
        
            | 
            | 
           661 | 
           // check can be removed.
  | 
        
        
            | 
            | 
           662 | 
           - (void)validateDelegateConformsToTokenAvailabilityMethods {
  | 
        
        
            | 
            | 
           663 | 
             if (self.delegate && ![self.delegate respondsToSelector:@selector(messaging:
  | 
        
        
            | 
            | 
           664 | 
                                                                         didReceiveRegistrationToken:)]) {
  | 
        
        
            | 
            | 
           665 | 
               FIRMessagingLoggerWarn(kFIRMessagingMessageCodeTokenDelegateMethodsNotImplemented,
  | 
        
        
            | 
            | 
           666 | 
                                      @"The object %@ does not respond to "
  | 
        
        
            | 
            | 
           667 | 
                                      @"-messaging:didReceiveRegistrationToken:. Please implement "
  | 
        
        
            | 
            | 
           668 | 
                                      @"-messaging:didReceiveRegistrationToken: to be provided with an FCM "
  | 
        
        
            | 
            | 
           669 | 
                                      @"token.",
  | 
        
        
            | 
            | 
           670 | 
                                      self.delegate.description);
  | 
        
        
            | 
            | 
           671 | 
             }
  | 
        
        
            | 
            | 
           672 | 
           }
  | 
        
        
            | 
            | 
           673 | 
              | 
        
        
            | 
            | 
           674 | 
           - (void)notifyRefreshedFCMToken {
  | 
        
        
            | 
            | 
           675 | 
             __weak FIRMessaging *weakSelf = self;
  | 
        
        
            | 
            | 
           676 | 
             if (![NSThread isMainThread]) {
  | 
        
        
            | 
            | 
           677 | 
               dispatch_async(dispatch_get_main_queue(), ^{
  | 
        
        
            | 
            | 
           678 | 
                 [weakSelf notifyRefreshedFCMToken];
  | 
        
        
            | 
            | 
           679 | 
               });
  | 
        
        
            | 
            | 
           680 | 
               return;
  | 
        
        
            | 
            | 
           681 | 
             }
  | 
        
        
            | 
            | 
           682 | 
             if ([self.delegate respondsToSelector:@selector(messaging:didReceiveRegistrationToken:)]) {
  | 
        
        
            | 
            | 
           683 | 
               [self.delegate messaging:self didReceiveRegistrationToken:self.tokenManager.defaultFCMToken];
  | 
        
        
            | 
            | 
           684 | 
             }
  | 
        
        
            | 
            | 
           685 | 
              | 
        
        
            | 
            | 
           686 | 
             // Should always trigger the token refresh notification when the delegate method is called
  | 
        
        
            | 
            | 
           687 | 
             NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
  | 
        
        
            | 
            | 
           688 | 
             [center postNotificationName:FIRMessagingRegistrationTokenRefreshedNotification
  | 
        
        
            | 
            | 
           689 | 
                                   object:self.tokenManager.defaultFCMToken];
  | 
        
        
            | 
            | 
           690 | 
           }
  | 
        
        
            | 
            | 
           691 | 
              | 
        
        
            | 
            | 
           692 | 
           #pragma mark - Topics
  | 
        
        
            | 
            | 
           693 | 
              | 
        
        
            | 
            | 
           694 | 
           + (NSString *)normalizeTopic:(NSString *)topic {
  | 
        
        
            | 
            | 
           695 | 
             if (!topic.length) {
  | 
        
        
            | 
            | 
           696 | 
               return nil;
  | 
        
        
            | 
            | 
           697 | 
             }
  | 
        
        
            | 
            | 
           698 | 
             if (![FIRMessagingPubSub hasTopicsPrefix:topic]) {
  | 
        
        
            | 
            | 
           699 | 
               topic = [FIRMessagingPubSub addPrefixToTopic:topic];
  | 
        
        
            | 
            | 
           700 | 
             }
  | 
        
        
            | 
            | 
           701 | 
             if ([FIRMessagingPubSub isValidTopicWithPrefix:topic]) {
  | 
        
        
            | 
            | 
           702 | 
               return [topic copy];
  | 
        
        
            | 
            | 
           703 | 
             }
  | 
        
        
            | 
            | 
           704 | 
             return nil;
  | 
        
        
            | 
            | 
           705 | 
           }
  | 
        
        
            | 
            | 
           706 | 
              | 
        
        
            | 
            | 
           707 | 
           - (void)subscribeToTopic:(NSString *)topic {
  | 
        
        
            | 
            | 
           708 | 
             [self subscribeToTopic:topic completion:nil];
  | 
        
        
            | 
            | 
           709 | 
           }
  | 
        
        
            | 
            | 
           710 | 
              | 
        
        
            | 
            | 
           711 | 
           - (void)subscribeToTopic:(NSString *)topic
  | 
        
        
            | 
            | 
           712 | 
                         completion:(nullable FIRMessagingTopicOperationCompletion)completion {
  | 
        
        
            | 
            | 
           713 | 
             if ([FIRMessagingPubSub hasTopicsPrefix:topic]) {
  | 
        
        
            | 
            | 
           714 | 
               FIRMessagingLoggerWarn(kFIRMessagingMessageCodeTopicFormatIsDeprecated,
  | 
        
        
            | 
            | 
           715 | 
                                      @"Format '%@' is deprecated. Only '%@' should be used in "
  | 
        
        
            | 
            | 
           716 | 
                                      @"subscribeToTopic.",
  | 
        
        
            | 
            | 
           717 | 
                                      topic, [FIRMessagingPubSub removePrefixFromTopic:topic]);
  | 
        
        
            | 
            | 
           718 | 
             }
  | 
        
        
            | 
            | 
           719 | 
             __weak FIRMessaging *weakSelf = self;
  | 
        
        
            | 
            | 
           720 | 
             [self
  | 
        
        
            | 
            | 
           721 | 
                 retrieveFCMTokenForSenderID:self.tokenManager.fcmSenderID
  | 
        
        
            | 
            | 
           722 | 
                                  completion:^(NSString *_Nullable FCMToken, NSError *_Nullable error) {
  | 
        
        
            | 
            | 
           723 | 
                                    if (error) {
  | 
        
        
            | 
            | 
           724 | 
                                      FIRMessagingLoggerError(kFIRMessagingMessageCodeMessaging010,
  | 
        
        
            | 
            | 
           725 | 
                                                              @"The subscription operation failed due to an "
  | 
        
        
            | 
            | 
           726 | 
                                                              @"error getting the FCM token: %@.",
  | 
        
        
            | 
            | 
           727 | 
                                                              error);
  | 
        
        
            | 
            | 
           728 | 
                                      if (completion) {
  | 
        
        
            | 
            | 
           729 | 
                                        completion(error);
  | 
        
        
            | 
            | 
           730 | 
                                      }
  | 
        
        
            | 
            | 
           731 | 
                                      return;
  | 
        
        
            | 
            | 
           732 | 
                                    }
  | 
        
        
            | 
            | 
           733 | 
                                    FIRMessaging *strongSelf = weakSelf;
  | 
        
        
            | 
            | 
           734 | 
                                    NSString *normalizeTopic = [[strongSelf class] normalizeTopic:topic];
  | 
        
        
            | 
            | 
           735 | 
                                    if (normalizeTopic.length) {
  | 
        
        
            | 
            | 
           736 | 
                                      [strongSelf.pubsub subscribeToTopic:normalizeTopic handler:completion];
  | 
        
        
            | 
            | 
           737 | 
                                      return;
  | 
        
        
            | 
            | 
           738 | 
                                    }
  | 
        
        
            | 
            | 
           739 | 
                                    NSString *failureReason = [NSString
  | 
        
        
            | 
            | 
           740 | 
                                        stringWithFormat:@"Cannot parse topic name: '%@'. Will not subscribe.",
  | 
        
        
            | 
            | 
           741 | 
                                                         topic];
  | 
        
        
            | 
            | 
           742 | 
                                    FIRMessagingLoggerError(kFIRMessagingMessageCodeMessaging009, @"%@",
  | 
        
        
            | 
            | 
           743 | 
                                                            failureReason);
  | 
        
        
            | 
            | 
           744 | 
                                    if (completion) {
  | 
        
        
            | 
            | 
           745 | 
                                      completion([NSError
  | 
        
        
            | 
            | 
           746 | 
                                          messagingErrorWithCode:kFIRMessagingErrorCodeInvalidTopicName
  | 
        
        
            | 
            | 
           747 | 
                                                   failureReason:failureReason]);
  | 
        
        
            | 
            | 
           748 | 
                                    }
  | 
        
        
            | 
            | 
           749 | 
                                  }];
  | 
        
        
            | 
            | 
           750 | 
           }
  | 
        
        
            | 
            | 
           751 | 
              | 
        
        
            | 
            | 
           752 | 
           - (void)unsubscribeFromTopic:(NSString *)topic {
  | 
        
        
            | 
            | 
           753 | 
             [self unsubscribeFromTopic:topic completion:nil];
  | 
        
        
            | 
            | 
           754 | 
           }
  | 
        
        
            | 
            | 
           755 | 
              | 
        
        
            | 
            | 
           756 | 
           - (void)unsubscribeFromTopic:(NSString *)topic
  | 
        
        
            | 
            | 
           757 | 
                             completion:(nullable FIRMessagingTopicOperationCompletion)completion {
  | 
        
        
            | 
            | 
           758 | 
             if ([FIRMessagingPubSub hasTopicsPrefix:topic]) {
  | 
        
        
            | 
            | 
           759 | 
               FIRMessagingLoggerWarn(kFIRMessagingMessageCodeTopicFormatIsDeprecated,
  | 
        
        
            | 
            | 
           760 | 
                                      @"Format '%@' is deprecated. Only '%@' should be used in "
  | 
        
        
            | 
            | 
           761 | 
                                      @"unsubscribeFromTopic.",
  | 
        
        
            | 
            | 
           762 | 
                                      topic, [FIRMessagingPubSub removePrefixFromTopic:topic]);
  | 
        
        
            | 
            | 
           763 | 
             }
  | 
        
        
            | 
            | 
           764 | 
             __weak FIRMessaging *weakSelf = self;
  | 
        
        
            | 
            | 
           765 | 
             [self retrieveFCMTokenForSenderID:self.tokenManager.fcmSenderID
  | 
        
        
            | 
            | 
           766 | 
                                    completion:^(NSString *_Nullable FCMToken, NSError *_Nullable error) {
  | 
        
        
            | 
            | 
           767 | 
                                      if (error) {
  | 
        
        
            | 
            | 
           768 | 
                                        FIRMessagingLoggerError(kFIRMessagingMessageCodeMessaging012,
  | 
        
        
            | 
            | 
           769 | 
                                                                @"The unsubscription operation failed due to "
  | 
        
        
            | 
            | 
           770 | 
                                                                @"an error getting the FCM token: %@.",
  | 
        
        
            | 
            | 
           771 | 
                                                                error);
  | 
        
        
            | 
            | 
           772 | 
                                        if (completion) {
  | 
        
        
            | 
            | 
           773 | 
                                          completion(error);
  | 
        
        
            | 
            | 
           774 | 
                                        }
  | 
        
        
            | 
            | 
           775 | 
                                        return;
  | 
        
        
            | 
            | 
           776 | 
                                      }
  | 
        
        
            | 
            | 
           777 | 
                                      FIRMessaging *strongSelf = weakSelf;
  | 
        
        
            | 
            | 
           778 | 
                                      NSString *normalizeTopic = [[strongSelf class] normalizeTopic:topic];
  | 
        
        
            | 
            | 
           779 | 
                                      if (normalizeTopic.length) {
  | 
        
        
            | 
            | 
           780 | 
                                        [strongSelf.pubsub unsubscribeFromTopic:normalizeTopic
  | 
        
        
            | 
            | 
           781 | 
                                                                        handler:completion];
  | 
        
        
            | 
            | 
           782 | 
                                        return;
  | 
        
        
            | 
            | 
           783 | 
                                      }
  | 
        
        
            | 
            | 
           784 | 
                                      NSString *failureReason = [NSString
  | 
        
        
            | 
            | 
           785 | 
                                          stringWithFormat:
  | 
        
        
            | 
            | 
           786 | 
                                              @"Cannot parse topic name: '%@'. Will not unsubscribe.", topic];
  | 
        
        
            | 
            | 
           787 | 
                                      FIRMessagingLoggerError(kFIRMessagingMessageCodeMessaging011, @"%@",
  | 
        
        
            | 
            | 
           788 | 
                                                              failureReason);
  | 
        
        
            | 
            | 
           789 | 
                                      if (completion) {
  | 
        
        
            | 
            | 
           790 | 
                                        completion([NSError
  | 
        
        
            | 
            | 
           791 | 
                                            messagingErrorWithCode:kFIRMessagingErrorCodeInvalidTopicName
  | 
        
        
            | 
            | 
           792 | 
                                                     failureReason:failureReason]);
  | 
        
        
            | 
            | 
           793 | 
                                      }
  | 
        
        
            | 
            | 
           794 | 
                                    }];
  | 
        
        
            | 
            | 
           795 | 
           }
  | 
        
        
            | 
            | 
           796 | 
              | 
        
        
            | 
            | 
           797 | 
           #pragma mark - GULReachabilityDelegate
  | 
        
        
            | 
            | 
           798 | 
              | 
        
        
            | 
            | 
           799 | 
           - (void)reachability:(GULReachabilityChecker *)reachability
  | 
        
        
            | 
            | 
           800 | 
                  statusChanged:(GULReachabilityStatus)status {
  | 
        
        
            | 
            | 
           801 | 
             [self onNetworkStatusChanged];
  | 
        
        
            | 
            | 
           802 | 
           }
  | 
        
        
            | 
            | 
           803 | 
              | 
        
        
            | 
            | 
           804 | 
           #pragma mark - Network
  | 
        
        
            | 
            | 
           805 | 
              | 
        
        
            | 
            | 
           806 | 
           - (void)onNetworkStatusChanged {
  | 
        
        
            | 
            | 
           807 | 
             if ([self isNetworkAvailable]) {
  | 
        
        
            | 
            | 
           808 | 
               [self.pubsub scheduleSync:YES];
  | 
        
        
            | 
            | 
           809 | 
             }
  | 
        
        
            | 
            | 
           810 | 
           }
  | 
        
        
            | 
            | 
           811 | 
              | 
        
        
            | 
            | 
           812 | 
           - (BOOL)isNetworkAvailable {
  | 
        
        
            | 
            | 
           813 | 
             GULReachabilityStatus status = self.reachability.reachabilityStatus;
  | 
        
        
            | 
            | 
           814 | 
             return (status == kGULReachabilityViaCellular || status == kGULReachabilityViaWifi);
  | 
        
        
            | 
            | 
           815 | 
           }
  | 
        
        
            | 
            | 
           816 | 
              | 
        
        
            | 
            | 
           817 | 
           - (FIRMessagingNetworkStatus)networkType {
  | 
        
        
            | 
            | 
           818 | 
             GULReachabilityStatus status = self.reachability.reachabilityStatus;
  | 
        
        
            | 
            | 
           819 | 
             if (![self isNetworkAvailable]) {
  | 
        
        
            | 
            | 
           820 | 
               return kFIRMessagingReachabilityNotReachable;
  | 
        
        
            | 
            | 
           821 | 
             } else if (status == kGULReachabilityViaCellular) {
  | 
        
        
            | 
            | 
           822 | 
               return kFIRMessagingReachabilityReachableViaWWAN;
  | 
        
        
            | 
            | 
           823 | 
             } else {
  | 
        
        
            | 
            | 
           824 | 
               return kFIRMessagingReachabilityReachableViaWiFi;
  | 
        
        
            | 
            | 
           825 | 
             }
  | 
        
        
            | 
            | 
           826 | 
           }
  | 
        
        
            | 
            | 
           827 | 
              | 
        
        
            | 
            | 
           828 | 
           #pragma mark - Notifications
  | 
        
        
            | 
            | 
           829 | 
              | 
        
        
            | 
            | 
           830 | 
           - (void)defaultFCMTokenWasRefreshed:(NSNotification *)notification {
  | 
        
        
            | 
            | 
           831 | 
             if (notification.object && ![notification.object isKindOfClass:[NSString class]]) {
  | 
        
        
            | 
            | 
           832 | 
               FIRMessagingLoggerDebug(kFIRMessagingMessageCodeMessaging015,
  | 
        
        
            | 
            | 
           833 | 
                                       @"Invalid default FCM token type %@",
  | 
        
        
            | 
            | 
           834 | 
                                       NSStringFromClass([notification.object class]));
  | 
        
        
            | 
            | 
           835 | 
               return;
  | 
        
        
            | 
            | 
           836 | 
             }
  | 
        
        
            | 
            | 
           837 | 
             NSString *newToken = [(NSString *)notification.object copy];
  | 
        
        
            | 
            | 
           838 | 
             [self updateDefaultFCMToken:newToken];
  | 
        
        
            | 
            | 
           839 | 
           }
  | 
        
        
            | 
            | 
           840 | 
              | 
        
        
            | 
            | 
           841 | 
           - (void)updateDefaultFCMToken:(NSString *)defaultFCMToken {
  | 
        
        
            | 
            | 
           842 | 
             NSString *oldToken = self.tokenManager.defaultFCMToken;
  | 
        
        
            | 
            | 
           843 | 
             NSString *newToken = defaultFCMToken;
  | 
        
        
            | 
            | 
           844 | 
             if ([self.tokenManager hasTokenChangedFromOldToken:oldToken toNewToken:newToken]) {
  | 
        
        
            | 
            | 
           845 | 
               // Make sure to set default token first before notifying others.
  | 
        
        
            | 
            | 
           846 | 
               [self.tokenManager saveDefaultTokenInfoInKeychain:newToken];
  | 
        
        
            | 
            | 
           847 | 
               [self notifyDelegateOfFCMTokenAvailability];
  | 
        
        
            | 
            | 
           848 | 
               [self.pubsub scheduleSync:YES];
  | 
        
        
            | 
            | 
           849 | 
             }
  | 
        
        
            | 
            | 
           850 | 
           }
  | 
        
        
            | 
            | 
           851 | 
              | 
        
        
            | 
            | 
           852 | 
           - (void)notifyDelegateOfFCMTokenAvailability {
  | 
        
        
            | 
            | 
           853 | 
             __weak FIRMessaging *weakSelf = self;
  | 
        
        
            | 
            | 
           854 | 
             if (![NSThread isMainThread]) {
  | 
        
        
            | 
            | 
           855 | 
               dispatch_async(dispatch_get_main_queue(), ^{
  | 
        
        
            | 
            | 
           856 | 
                 [weakSelf notifyDelegateOfFCMTokenAvailability];
  | 
        
        
            | 
            | 
           857 | 
               });
  | 
        
        
            | 
            | 
           858 | 
               return;
  | 
        
        
            | 
            | 
           859 | 
             }
  | 
        
        
            | 
            | 
           860 | 
             if ([self.delegate respondsToSelector:@selector(messaging:didReceiveRegistrationToken:)]) {
  | 
        
        
            | 
            | 
           861 | 
               [self.delegate messaging:self didReceiveRegistrationToken:self.tokenManager.defaultFCMToken];
  | 
        
        
            | 
            | 
           862 | 
             }
  | 
        
        
            | 
            | 
           863 | 
             // Should always trigger the token refresh notification when the delegate method is called
  | 
        
        
            | 
            | 
           864 | 
             NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
  | 
        
        
            | 
            | 
           865 | 
             [center postNotificationName:FIRMessagingRegistrationTokenRefreshedNotification
  | 
        
        
            | 
            | 
           866 | 
                                   object:self.tokenManager.defaultFCMToken];
  | 
        
        
            | 
            | 
           867 | 
           }
  | 
        
        
            | 
            | 
           868 | 
              | 
        
        
            | 
            | 
           869 | 
           #pragma mark - Application Support Directory
  | 
        
        
            | 
            | 
           870 | 
              | 
        
        
            | 
            | 
           871 | 
           + (BOOL)hasSubDirectory:(NSString *)subDirectoryName {
  | 
        
        
            | 
            | 
           872 | 
             NSString *subDirectoryPath = [self pathForSubDirectory:subDirectoryName];
  | 
        
        
            | 
            | 
           873 | 
             BOOL isDirectory;
  | 
        
        
            | 
            | 
           874 | 
             if (![[NSFileManager defaultManager] fileExistsAtPath:subDirectoryPath
  | 
        
        
            | 
            | 
           875 | 
                                                       isDirectory:&isDirectory]) {
  | 
        
        
            | 
            | 
           876 | 
               return NO;
  | 
        
        
            | 
            | 
           877 | 
             } else if (!isDirectory) {
  | 
        
        
            | 
            | 
           878 | 
               return NO;
  | 
        
        
            | 
            | 
           879 | 
             }
  | 
        
        
            | 
            | 
           880 | 
             return YES;
  | 
        
        
            | 
            | 
           881 | 
           }
  | 
        
        
            | 
            | 
           882 | 
              | 
        
        
            | 
            | 
           883 | 
           + (NSString *)pathForSubDirectory:(NSString *)subDirectoryName {
  | 
        
        
            | 
            | 
           884 | 
             NSArray *directoryPaths =
  | 
        
        
            | 
            | 
           885 | 
                 NSSearchPathForDirectoriesInDomains(FIRMessagingSupportedDirectory(), NSUserDomainMask, YES);
  | 
        
        
            | 
            | 
           886 | 
             NSString *dirPath = directoryPaths.lastObject;
  | 
        
        
            | 
            | 
           887 | 
             NSArray *components = @[ dirPath, subDirectoryName ];
  | 
        
        
            | 
            | 
           888 | 
             return [NSString pathWithComponents:components];
  | 
        
        
            | 
            | 
           889 | 
           }
  | 
        
        
            | 
            | 
           890 | 
              | 
        
        
            | 
            | 
           891 | 
           + (BOOL)createSubDirectory:(NSString *)subDirectoryName {
  | 
        
        
            | 
            | 
           892 | 
             NSString *subDirectoryPath = [self pathForSubDirectory:subDirectoryName];
  | 
        
        
            | 
            | 
           893 | 
             BOOL hasSubDirectory;
  | 
        
        
            | 
            | 
           894 | 
              | 
        
        
            | 
            | 
           895 | 
             if (![[NSFileManager defaultManager] fileExistsAtPath:subDirectoryPath
  | 
        
        
            | 
            | 
           896 | 
                                                       isDirectory:&hasSubDirectory]) {
  | 
        
        
            | 
            | 
           897 | 
               NSError *error;
  | 
        
        
            | 
            | 
           898 | 
               [[NSFileManager defaultManager] createDirectoryAtPath:subDirectoryPath
  | 
        
        
            | 
            | 
           899 | 
                                         withIntermediateDirectories:YES
  | 
        
        
            | 
            | 
           900 | 
                                                          attributes:nil
  | 
        
        
            | 
            | 
           901 | 
                                                               error:&error];
  | 
        
        
            | 
            | 
           902 | 
               if (error) {
  | 
        
        
            | 
            | 
           903 | 
                 FIRMessagingLoggerError(kFIRMessagingMessageCodeMessaging017,
  | 
        
        
            | 
            | 
           904 | 
                                         @"Cannot create directory %@, error: %@", subDirectoryPath, error);
  | 
        
        
            | 
            | 
           905 | 
                 return NO;
  | 
        
        
            | 
            | 
           906 | 
               }
  | 
        
        
            | 
            | 
           907 | 
             } else {
  | 
        
        
            | 
            | 
           908 | 
               if (!hasSubDirectory) {
  | 
        
        
            | 
            | 
           909 | 
                 FIRMessagingLoggerError(kFIRMessagingMessageCodeMessaging018,
  | 
        
        
            | 
            | 
           910 | 
                                         @"Found file instead of directory at %@", subDirectoryPath);
  | 
        
        
            | 
            | 
           911 | 
                 return NO;
  | 
        
        
            | 
            | 
           912 | 
               }
  | 
        
        
            | 
            | 
           913 | 
             }
  | 
        
        
            | 
            | 
           914 | 
             return YES;
  | 
        
        
            | 
            | 
           915 | 
           }
  | 
        
        
            | 
            | 
           916 | 
              | 
        
        
            | 
            | 
           917 | 
           #pragma mark - Locales
  | 
        
        
            | 
            | 
           918 | 
              | 
        
        
            | 
            | 
           919 | 
           + (NSString *)currentLocale {
  | 
        
        
            | 
            | 
           920 | 
             NSArray *locales = [self firebaseLocales];
  | 
        
        
            | 
            | 
           921 | 
             NSArray *preferredLocalizations =
  | 
        
        
            | 
            | 
           922 | 
                 [NSBundle preferredLocalizationsFromArray:locales
  | 
        
        
            | 
            | 
           923 | 
                                            forPreferences:[NSLocale preferredLanguages]];
  | 
        
        
            | 
            | 
           924 | 
             NSString *legalDocsLanguage = [preferredLocalizations firstObject];
  | 
        
        
            | 
            | 
           925 | 
             // Use en as the default language
  | 
        
        
            | 
            | 
           926 | 
             return legalDocsLanguage ? legalDocsLanguage : @"en";
  | 
        
        
            | 
            | 
           927 | 
           }
  | 
        
        
            | 
            | 
           928 | 
              | 
        
        
            | 
            | 
           929 | 
           + (NSArray *)firebaseLocales {
  | 
        
        
            | 
            | 
           930 | 
             NSMutableArray *locales = [NSMutableArray array];
  | 
        
        
            | 
            | 
           931 | 
             NSDictionary *localesMap = [self firebaselocalesMap];
  | 
        
        
            | 
            | 
           932 | 
             for (NSString *key in localesMap) {
  | 
        
        
            | 
            | 
           933 | 
               [locales addObjectsFromArray:localesMap[key]];
  | 
        
        
            | 
            | 
           934 | 
             }
  | 
        
        
            | 
            | 
           935 | 
             return locales;
  | 
        
        
            | 
            | 
           936 | 
           }
  | 
        
        
            | 
            | 
           937 | 
              | 
        
        
            | 
            | 
           938 | 
           + (NSDictionary *)firebaselocalesMap {
  | 
        
        
            | 
            | 
           939 | 
             return @{
  | 
        
        
            | 
            | 
           940 | 
               // Albanian
  | 
        
        
            | 
            | 
           941 | 
               @"sq" : @[ @"sq_AL" ],
  | 
        
        
            | 
            | 
           942 | 
               // Belarusian
  | 
        
        
            | 
            | 
           943 | 
               @"be" : @[ @"be_BY" ],
  | 
        
        
            | 
            | 
           944 | 
               // Bulgarian
  | 
        
        
            | 
            | 
           945 | 
               @"bg" : @[ @"bg_BG" ],
  | 
        
        
            | 
            | 
           946 | 
               // Catalan
  | 
        
        
            | 
            | 
           947 | 
               @"ca" : @[ @"ca", @"ca_ES" ],
  | 
        
        
            | 
            | 
           948 | 
               // Croatian
  | 
        
        
            | 
            | 
           949 | 
               @"hr" : @[ @"hr", @"hr_HR" ],
  | 
        
        
            | 
            | 
           950 | 
               // Czech
  | 
        
        
            | 
            | 
           951 | 
               @"cs" : @[ @"cs", @"cs_CZ" ],
  | 
        
        
            | 
            | 
           952 | 
               // Danish
  | 
        
        
            | 
            | 
           953 | 
               @"da" : @[ @"da", @"da_DK" ],
  | 
        
        
            | 
            | 
           954 | 
               // Estonian
  | 
        
        
            | 
            | 
           955 | 
               @"et" : @[ @"et_EE" ],
  | 
        
        
            | 
            | 
           956 | 
               // Finnish
  | 
        
        
            | 
            | 
           957 | 
               @"fi" : @[ @"fi", @"fi_FI" ],
  | 
        
        
            | 
            | 
           958 | 
               // Hebrew
  | 
        
        
            | 
            | 
           959 | 
               @"he" : @[ @"he", @"iw_IL" ],
  | 
        
        
            | 
            | 
           960 | 
               // Hindi
  | 
        
        
            | 
            | 
           961 | 
               @"hi" : @[ @"hi_IN" ],
  | 
        
        
            | 
            | 
           962 | 
               // Hungarian
  | 
        
        
            | 
            | 
           963 | 
               @"hu" : @[ @"hu", @"hu_HU" ],
  | 
        
        
            | 
            | 
           964 | 
               // Icelandic
  | 
        
        
            | 
            | 
           965 | 
               @"is" : @[ @"is_IS" ],
  | 
        
        
            | 
            | 
           966 | 
               // Indonesian
  | 
        
        
            | 
            | 
           967 | 
               @"id" : @[ @"id", @"in_ID", @"id_ID" ],
  | 
        
        
            | 
            | 
           968 | 
               // Irish
  | 
        
        
            | 
            | 
           969 | 
               @"ga" : @[ @"ga_IE" ],
  | 
        
        
            | 
            | 
           970 | 
               // Korean
  | 
        
        
            | 
            | 
           971 | 
               @"ko" : @[ @"ko", @"ko_KR", @"ko-KR" ],
  | 
        
        
            | 
            | 
           972 | 
               // Latvian
  | 
        
        
            | 
            | 
           973 | 
               @"lv" : @[ @"lv_LV" ],
  | 
        
        
            | 
            | 
           974 | 
               // Lithuanian
  | 
        
        
            | 
            | 
           975 | 
               @"lt" : @[ @"lt_LT" ],
  | 
        
        
            | 
            | 
           976 | 
               // Macedonian
  | 
        
        
            | 
            | 
           977 | 
               @"mk" : @[ @"mk_MK" ],
  | 
        
        
            | 
            | 
           978 | 
               // Malay
  | 
        
        
            | 
            | 
           979 | 
               @"ms" : @[ @"ms_MY" ],
  | 
        
        
            | 
            | 
           980 | 
               // Maltese
  | 
        
        
            | 
            | 
           981 | 
               @"mt" : @[ @"mt_MT" ],
  | 
        
        
            | 
            | 
           982 | 
               // Polish
  | 
        
        
            | 
            | 
           983 | 
               @"pl" : @[ @"pl", @"pl_PL", @"pl-PL" ],
  | 
        
        
            | 
            | 
           984 | 
               // Romanian
  | 
        
        
            | 
            | 
           985 | 
               @"ro" : @[ @"ro", @"ro_RO" ],
  | 
        
        
            | 
            | 
           986 | 
               // Russian
  | 
        
        
            | 
            | 
           987 | 
               @"ru" : @[ @"ru_RU", @"ru", @"ru_BY", @"ru_KZ", @"ru-RU" ],
  | 
        
        
            | 
            | 
           988 | 
               // Slovak
  | 
        
        
            | 
            | 
           989 | 
               @"sk" : @[ @"sk", @"sk_SK" ],
  | 
        
        
            | 
            | 
           990 | 
               // Slovenian
  | 
        
        
            | 
            | 
           991 | 
               @"sl" : @[ @"sl_SI" ],
  | 
        
        
            | 
            | 
           992 | 
               // Swedish
  | 
        
        
            | 
            | 
           993 | 
               @"sv" : @[ @"sv", @"sv_SE", @"sv-SE" ],
  | 
        
        
            | 
            | 
           994 | 
               // Turkish
  | 
        
        
            | 
            | 
           995 | 
               @"tr" : @[ @"tr", @"tr-TR", @"tr_TR" ],
  | 
        
        
            | 
            | 
           996 | 
               // Ukrainian
  | 
        
        
            | 
            | 
           997 | 
               @"uk" : @[ @"uk", @"uk_UA" ],
  | 
        
        
            | 
            | 
           998 | 
               // Vietnamese
  | 
        
        
            | 
            | 
           999 | 
               @"vi" : @[ @"vi", @"vi_VN" ],
  | 
        
        
            | 
            | 
           1000 | 
               // The following are groups of locales or locales that sub-divide a
  | 
        
        
            | 
            | 
           1001 | 
               // language).
  | 
        
        
            | 
            | 
           1002 | 
               // Arabic
  | 
        
        
            | 
            | 
           1003 | 
               @"ar" : @[
  | 
        
        
            | 
            | 
           1004 | 
                 @"ar",    @"ar_DZ", @"ar_BH", @"ar_EG", @"ar_IQ", @"ar_JO", @"ar_KW",
  | 
        
        
            | 
            | 
           1005 | 
                 @"ar_LB", @"ar_LY", @"ar_MA", @"ar_OM", @"ar_QA", @"ar_SA", @"ar_SD",
  | 
        
        
            | 
            | 
           1006 | 
                 @"ar_SY", @"ar_TN", @"ar_AE", @"ar_YE", @"ar_GB", @"ar-IQ", @"ar_US"
  | 
        
        
            | 
            | 
           1007 | 
               ],
  | 
        
        
            | 
            | 
           1008 | 
               // Simplified Chinese
  | 
        
        
            | 
            | 
           1009 | 
               @"zh_Hans" : @[ @"zh_CN", @"zh_SG", @"zh-Hans" ],
  | 
        
        
            | 
            | 
           1010 | 
               // Traditional Chinese
  | 
        
        
            | 
            | 
           1011 | 
               @"zh_Hant" : @[ @"zh_HK", @"zh_TW", @"zh-Hant", @"zh-HK", @"zh-TW" ],
  | 
        
        
            | 
            | 
           1012 | 
               // Dutch
  | 
        
        
            | 
            | 
           1013 | 
               @"nl" : @[ @"nl", @"nl_BE", @"nl_NL", @"nl-NL" ],
  | 
        
        
            | 
            | 
           1014 | 
               // English
  | 
        
        
            | 
            | 
           1015 | 
               @"en" : @[
  | 
        
        
            | 
            | 
           1016 | 
                 @"en",    @"en_AU", @"en_CA", @"en_IN", @"en_IE", @"en_MT", @"en_NZ", @"en_PH",
  | 
        
        
            | 
            | 
           1017 | 
                 @"en_SG", @"en_ZA", @"en_GB", @"en_US", @"en_AE", @"en-AE", @"en_AS", @"en-AU",
  | 
        
        
            | 
            | 
           1018 | 
                 @"en_BD", @"en-CA", @"en_EG", @"en_ES", @"en_GB", @"en-GB", @"en_HK", @"en_ID",
  | 
        
        
            | 
            | 
           1019 | 
                 @"en-IN", @"en_NG", @"en-PH", @"en_PK", @"en-SG", @"en-US"
  | 
        
        
            | 
            | 
           1020 | 
               ],
  | 
        
        
            | 
            | 
           1021 | 
               // French
  | 
        
        
            | 
            | 
           1022 | 
              | 
        
        
            | 
            | 
           1023 | 
               @"fr" :
  | 
        
        
            | 
            | 
           1024 | 
                   @[ @"fr", @"fr_BE", @"fr_CA", @"fr_FR", @"fr_LU", @"fr_CH", @"fr-CA", @"fr-FR", @"fr_MA" ],
  | 
        
        
            | 
            | 
           1025 | 
               // German
  | 
        
        
            | 
            | 
           1026 | 
               @"de" : @[ @"de", @"de_AT", @"de_DE", @"de_LU", @"de_CH", @"de-DE" ],
  | 
        
        
            | 
            | 
           1027 | 
               // Greek
  | 
        
        
            | 
            | 
           1028 | 
               @"el" : @[ @"el", @"el_CY", @"el_GR" ],
  | 
        
        
            | 
            | 
           1029 | 
               // Italian
  | 
        
        
            | 
            | 
           1030 | 
               @"it" : @[ @"it", @"it_IT", @"it_CH", @"it-IT" ],
  | 
        
        
            | 
            | 
           1031 | 
               // Japanese
  | 
        
        
            | 
            | 
           1032 | 
               @"ja" : @[ @"ja", @"ja_JP", @"ja_JP_JP", @"ja-JP" ],
  | 
        
        
            | 
            | 
           1033 | 
               // Norwegian
  | 
        
        
            | 
            | 
           1034 | 
               @"no" : @[ @"nb", @"no_NO", @"no_NO_NY", @"nb_NO" ],
  | 
        
        
            | 
            | 
           1035 | 
               // Brazilian Portuguese
  | 
        
        
            | 
            | 
           1036 | 
               @"pt_BR" : @[ @"pt_BR", @"pt-BR" ],
  | 
        
        
            | 
            | 
           1037 | 
               // European Portuguese
  | 
        
        
            | 
            | 
           1038 | 
               @"pt_PT" : @[ @"pt", @"pt_PT", @"pt-PT" ],
  | 
        
        
            | 
            | 
           1039 | 
               // Serbian
  | 
        
        
            | 
            | 
           1040 | 
               @"sr" : @[ @"sr_BA", @"sr_ME", @"sr_RS", @"sr_Latn_BA", @"sr_Latn_ME", @"sr_Latn_RS" ],
  | 
        
        
            | 
            | 
           1041 | 
               // European Spanish
  | 
        
        
            | 
            | 
           1042 | 
               @"es_ES" : @[ @"es", @"es_ES", @"es-ES" ],
  | 
        
        
            | 
            | 
           1043 | 
               // Mexican Spanish
  | 
        
        
            | 
            | 
           1044 | 
               @"es_MX" : @[ @"es-MX", @"es_MX", @"es_US", @"es-US" ],
  | 
        
        
            | 
            | 
           1045 | 
               // Latin American Spanish
  | 
        
        
            | 
            | 
           1046 | 
               @"es_419" : @[
  | 
        
        
            | 
            | 
           1047 | 
                 @"es_AR", @"es_BO", @"es_CL", @"es_CO", @"es_CR", @"es_DO", @"es_EC",
  | 
        
        
            | 
            | 
           1048 | 
                 @"es_SV", @"es_GT", @"es_HN", @"es_NI", @"es_PA", @"es_PY", @"es_PE",
  | 
        
        
            | 
            | 
           1049 | 
                 @"es_PR", @"es_UY", @"es_VE", @"es-AR", @"es-CL", @"es-CO"
  | 
        
        
            | 
            | 
           1050 | 
               ],
  | 
        
        
            | 
            | 
           1051 | 
               // Thai
  | 
        
        
            | 
            | 
           1052 | 
               @"th" : @[ @"th", @"th_TH", @"th_TH_TH" ],
  | 
        
        
            | 
            | 
           1053 | 
             };
  | 
        
        
            | 
            | 
           1054 | 
           }
  | 
        
        
            | 
            | 
           1055 | 
              | 
        
        
            | 
            | 
           1056 | 
           #pragma mark - Utilities used by InstanceID
  | 
        
        
            | 
            | 
           1057 | 
              | 
        
        
            | 
            | 
           1058 | 
           + (NSString *)FIRMessagingSDKVersion {
  | 
        
        
            | 
            | 
           1059 | 
             return FIRFirebaseVersion();
  | 
        
        
            | 
            | 
           1060 | 
           }
  | 
        
        
            | 
            | 
           1061 | 
              | 
        
        
            | 
            | 
           1062 | 
           + (NSString *)FIRMessagingSDKCurrentLocale {
  | 
        
        
            | 
            | 
           1063 | 
             return [self currentLocale];
  | 
        
        
            | 
            | 
           1064 | 
           }
  | 
        
        
            | 
            | 
           1065 | 
              | 
        
        
            | 
            | 
           1066 | 
           @end
  |