-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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(dynamic-links,android): getInitialLink returned more than once, and sometimes returned null #4735
fix(dynamic-links,android): getInitialLink returned more than once, and sometimes returned null #4735
Conversation
This pull request is being automatically deployed with Vercel (learn more). 🔍 Inspect: https://vercel.com/invertase/react-native-firebase/ekhbjo153 |
Codecov Report
@@ Coverage Diff @@
## master #4735 +/- ##
==========================================
+ Coverage 85.48% 89.09% +3.61%
==========================================
Files 109 109
Lines 3712 3712
Branches 347 347
==========================================
+ Hits 3173 3307 +134
+ Misses 473 363 -110
+ Partials 66 42 -24 |
Hi there! Thanks for posting this, it looks like it is solving a real problem. However I have some clarifying questions in order to understand it since the code is not immediately obvious
Am I correct in understanding that the first issue was already addressed but the previous solution is just incomplete for a specific condition? That condition being on app background / resume:
The language used here makes this seem like it is not handled at all but in order to understand the PR I need to be sure that I'm understanding: we already attempt to handle this firebase-ios-sdk behavior in a way react-native-firebase consumers want (get data then clear it), just that it is not working 100%. Otherwise I'm not sure why the
Assuming I understand correctly that the module already attempts to handle it, this part is not clear to me. So if I understand this correctly:
What if link is marked as fetched, app is in background, and user opens a distinct / different link? Should the initialLinkUrl itself be stored and used as the canary (instead of a gotInitialLink boolean) and then compared to see if it's different? 🤔 |
Hi, thanks for the quick reply!
Yes that's correct, mostly for the special case that is "backgrounded using the back button".
I'm sorry, I didn't mean to say that it's not handled at all, I've only managed to reproduce
I don't think so, if the app was not backgrounded using the back button and then a link is opened, this will be handled by the onNewIntent hook (onLink). I actually haven't thought about calling |
Okay - thanks for the thoughtful reply Can I ask you to clarify what you mean by "host"? In terms of react-native on Android I'm aware of the Android Application as a thing, I'm aware of the bridge, and I'm aware of the JS bundle running on the JS thread. When you say host, do you mean the Catalyst bridge? I think you do but I want to be clear - I don't think the actual words we use are that important I just have to make sure we're talking about the same concepts Assuming this is correct, can you lay out (like you did in steps 1-6 above) the same or similar steps but this time also detailing for the error case exactly what state each of the 3 react-native app components is in (e.g. "Android Application Resumed, bridge up, original JS thread running", or "Android Application Paused, bridge down, JS thread destroyed", or "Android Application Resumed, bridge up, JS thread 2 running after bridge re-init" or similar) I think you're on to something real here but I haven't probed this corner case and am not set up to reproduce it so I'll trust you on handling the corner cases etc One thing I would like is a comment next to each member variable in the code explaining the state it is tracking, and then on the conditionals that test the new state variables, a comment explaining the state transition that we are looking for (and guarding against, basically) |
I'm not very familiar with React Native's (or Java's) internals, the reason I mentioned "host" was because the lifecycle method referred to "host" as in
I'm not sure how to check all of those mentioned above, if you could assist in pointing me in the right direction I'd be happy to provide information.
Pushed a commit with some adjustments and comments as requested. |
Cool - thanks for that - I'll re-queue this for review, that application state logging is key to understanding which part of the application (and what state it is in...) which should help me read through this and make sure I understand it. I mean, I think I do already but most the PRs here don't actually add state and state tracking to the system, being a glorified wrapper over an SDK makes for easy PRs normally, and I just want to make sure if I/we approve adding state that I/we get it right :-). Cheers |
cool, thanks! |
I think this is likely a case where adding state is the only way to handle it as the JS thread + bridge (the Activity in Android terms but the whole application from developer's perspective) in react-native can have divergent state from native (the Application in Android terms) so it actually makes sense, I'm looking at it from the perspective of 99% sure I'm going to merge, possibly as-is from current PR state FWIW My pleasure on the maintenance, I do enjoy making things work |
Oh - the CLA must be signed though - please click the details link on that CI failure and do the needful for it to go green |
Sounds good. Thanks for the detailed explanation.
Done 👍 |
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.
Nice!
I had only non-semantic changes (trivial whitespace etc) - this LGTM on a re-re-read ;-)
There was an unrelated timeout / CI failure on android which is unfortunate because this affects Android code. I'm waiting for a green CI run there then I can merge this
.../src/main/java/io/invertase/firebase/dynamiclinks/ReactNativeFirebaseDynamicLinksModule.java
Outdated
Show resolved
Hide resolved
.../src/main/java/io/invertase/firebase/dynamiclinks/ReactNativeFirebaseDynamicLinksModule.java
Outdated
Show resolved
Hide resolved
.../src/main/java/io/invertase/firebase/dynamiclinks/ReactNativeFirebaseDynamicLinksModule.java
Outdated
Show resolved
Hide resolved
.../src/main/java/io/invertase/firebase/dynamiclinks/ReactNativeFirebaseDynamicLinksModule.java
Outdated
Show resolved
Hide resolved
CI went green! This should go out as 10.5.2 shortly, thanks! |
Do you have the same behavior on iOS as well? @mikehardy @sharc7 |
@ivanstnsk The majority of this fix was peculiar to the interaction between android lifecycle / react-native design, with a sort of side fix of not returning the dynamic link multiple times. On iOS it is possible it still returns the same dynamic link multiple times if you call getInitialLink multiple times but I'm not 100%, have you tested it? |
@mikehardy I've discovered exactly the same behavior on iOS - the getInitialLink is not clearing the link after handling. Tested on @react-native-firebase/dynamic-links v10.5.1 |
@ivanstnsk I am not surprised - I'd welcome a PR to fix it and happily work with anyone that proposes them |
Awesome, thank you! 😄 🚀 |
Description
This PR addresses two issue:
getInitialLink
link is returned more than once.getInitialLink
returns null.getInitialLink
.(as stated in the official docs:
Calling getDynamicLink() retrieves the link and clears that data so it is only processed once by your app.
)This causes the link to be retrieved even when returning to the app from the Overview screen after backgrounding the app using the back button, which leads to unwanted results such as deep links being handled more than once.
getInitialLink
is called before the host is resumed,getCurrentActivity
will be null andgetInitialLink
will return null instead of trying togetDynamicLink
.Related issues
Fixes #3990
Fixes #3027
Release Summary
Checklist
Android
iOS
e2e
tests added or updated inpackages/\*\*/e2e
jest
tests added or updated inpackages/\*\*/__tests__
Test Plan
Think
react-native-firebase
is great? Please consider supporting the project with any of the below:React Native Firebase
andInvertase
on Twitter🔥