-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix container instantiation timing, IID startup. #4030
Conversation
The container instantiation could happen at the wrong time, before all components have been added to the container. This fixes it, and also moves IID to use the proper instantiation timing instead of relying on the `configureWithApp:` call. This is part continuation of #3147, where I'll be fixing the rest of the SDKs in follow up PRs.
This moves the instantiation of components to after the FirebaseApp is completely configured and assigned, as it should be. This also exposed a recursive issue with IID calling the Messaging singleton, which in turn called IID and instantiated multiple instances. A change was made to break the cycle: the Messaging `isAutoInitEnabled` call was changed to a static method vs an instance method, allowing IID to call it during initialization without instantiating the Messaging instance (since it doesn't have a direct dependency on it).
@@ -22,6 +22,7 @@ | |||
#import <FirebaseInstanceID/FirebaseInstanceID.h> | |||
#import <FirebaseAnalyticsInterop/FIRAnalyticsInterop.h> | |||
#import <FirebaseMessaging/FIRMessaging.h> | |||
#import <GoogleUtilities/GULUserDefaults.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This import doesn't seem to be needed since the class uses NSUserDefaults directly
Firebase/Messaging/FIRMessaging.m
Outdated
/// exposed as a class property for IID to fetch the property without instantiating an instance of | ||
/// Messaging. Since Messaging can only be used with the default FIRApp, we can have one point of | ||
/// entry without context of which FIRApp instance is being used. | ||
/// ** THIS METHOD IS DEPENDED ON INTERNALLY BY IID. PLEASE DO NOT CHANGE THE SIGNATURE. ** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From my read it looks like isAutoInitEnabled
is depended upon by Messaging. isAutoInitEnabledWithUserDefaults
is only depended upon by the tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nvm, I missed the call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment doesn't strongly enough indicate that the call is made reflectively so it won't necessarily show up in find usages.
Firebase/Messaging/FIRMessaging.m
Outdated
/// exposed as a class property for IID to fetch the property without instantiating an instance of | ||
/// Messaging. Since Messaging can only be used with the default FIRApp, we can have one point of | ||
/// entry without context of which FIRApp instance is being used. | ||
/// ** THIS METHOD IS DEPENDED ON INTERNALLY BY IID. PLEASE DO NOT CHANGE THE SIGNATURE. ** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nvm, I missed the call.
Discussed offline with @paulb777 - we'll look at fixing the IID dependency on Messaging in a follow up PR by making Messaging instantiate first and initialize IID appropriately. |
BOOL (*isAutoInitEnabled)(id, SEL) = (BOOL(*)(id, SEL))isAutoInitEnabledIMP; | ||
// Get the autoInitEnabled class method. | ||
IMP isAutoInitEnabledIMP = [messagingClass methodForSelector:autoInitSelector]; | ||
BOOL(*isAutoInitEnabled) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe you can cast through (void *)
to avoid repeating yourself on the right hand side of this statement.
} | ||
|
||
// All eager instantiation is complete, empty and clear the stored property now. | ||
[self.eagerProtocolsToInstantiate removeAllObjects]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assigning nil
is sufficient to release all the contents of the array.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed, thanks.
// InstanceID only works with the default app. | ||
if (!container.app.isDefaultApp) { | ||
// Only configure for the default FIRApp. | ||
FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeFIRApp002, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be a warning or even an error?
Feel free to ignore--I see that this is just copypasta from the prior state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is also a "this code should never be run" so maybe it should be an error, but I'll leave it as is since it was copied from before.
Firebase/Messaging/FIRMessaging.m
Outdated
/// exposed as a class property for IID to fetch the property without instantiating an instance of | ||
/// Messaging. Since Messaging can only be used with the default FIRApp, we can have one point of | ||
/// entry without context of which FIRApp instance is being used. | ||
/// ** THIS METHOD IS DEPENDED ON INTERNALLY BY IID. PLEASE DO NOT CHANGE THE SIGNATURE. ** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment doesn't strongly enough indicate that the call is made reflectively so it won't necessarily show up in find usages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All my comments are optional, so LGTM
The container instantiation could happen at the wrong time, before all
components have been added to the container. This fixes it, and also
moves IID to use the proper instantiation timing instead of relying on
the
configureWithApp:
call. This is part continuation of #3147, whereI'll be fixing the rest of the SDKs in follow up PRs.
Edit: Further work...
This moves the instantiation of components to after the FirebaseApp is
completely configured and assigned, as it should be. This also exposed
a recursive issue with IID calling the Messaging singleton, which in
turn called IID and instantiated multiple instances.
A change was made to break the cycle: the Messaging
isAutoInitEnabled
call was changed to a static method vs an instance method, allowing IID
to call it during initialization without instantiating the Messaging
instance (since it doesn't have a direct dependency on it).