Skip to content

Conversation

@LorenzoBloedow
Copy link
Contributor

@LorenzoBloedow LorenzoBloedow commented Jul 14, 2025

Explanation of Change

This is a migration from withOnyx HOC to useOnyx hook in AuthScreens.

Fixed Issues

$ #65970
PROPOSAL: #65970 (comment)

MOBILE-EXPENSIFY: https://github.com/Expensify/Mobile-Expensify/pull/66093

Tests

Web/Desktop:

Relogin bug:

  1. Log out of ND on desktop app if logged in.
  2. Log into desktop app with deep link from web.
  3. Log out of desktop app.
  4. Verify that you've been able to log out without being logged in again.

Not found page bug 1:

  1. Log out of ND on desktop app if logged in.
  2. Log into desktop app with deep link from web.
  3. Log out of desktop app.
  4. Log in with a different account on desktop app.
  5. Verify you've been redirected to the last opened report instead of an infinite loading screen or not found page.

Not found page bug 2:

  1. Open ND in incognito window.
  2. Enter a new Gmail account.
  3. Select Something else.
  4. Enter name > Next.
  5. Go to Settings > Log out.
  6. Repeat Steps 2 to 4 with a different NEW account.
  7. Verify the Concierge chat opens.

Infinite loading bug 1:

  1. Open the desktop app.
  2. Verify it successfully loads.

Infinite loading bug 2:

  1. Open ND in incognito window.
  2. Enter a new Gmail account.
  3. Select Something else.
  4. Enter name > Next.
  5. Go to Settings > Log out.
  6. Repeat Steps 2 to 4 with an EXISTING account.
  7. Verify the last opened report in the existing account opens.

Blank screen with magic link bug:

  1. Log out of ND and request a new magic link as a gmail user.
  2. Close the login tab after the code has been sent.
  3. Navigate to email and locate the magic link.
  4. Change the URL to point to staging/dev/adhoc if needed.
  5. Open a new incognito window and navigate to the staging link.
  6. Click on the link to "Sign in here" on "Here is your code" page.
  7. Verify it loads without a blank page and without needing to refresh the page.

iOS:

  1. Log in with any account.
  2. Verify no plain white screen appears (besides skeleton) while loading app.

Offline tests

N/A

QA Steps

Same as tests.

PR Author Checklist

  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for the expected offline behavior in the Offline steps section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
    • I tested this PR with a High Traffic account against the staging or production API to ensure there are no regressions (e.g. long loading states that impact usability).
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • Android: Native
    • Android: mWeb Chrome
    • iOS: Native
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
    • MacOS: Desktop
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I verified there are no new alerts related to the canBeMissing param for useOnyx
  • I followed proper code patterns (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick)
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text shown in the product is localized by adding it to src/languages/* files and using the translation method
      • If any non-english text was added/modified, I used JaimeGPT to get English > Spanish translation. I then posted it in #expensify-open-source and it was approved by an internal Expensify engineer. Link to Slack message:
    • I verified all numbers, amounts, dates and phone numbers shown in the product are using the localization methods
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named "index.js". All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I followed the guidelines as stated in the Review Guidelines
  • I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.ts or at the top of the file that uses the constant) are defined as such
  • I verified that if a function's arguments changed that all usages have also been updated correctly
  • If any new file was added I verified that:
    • The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label and/or tagged @Expensify/design so the design team can review the changes.
  • If a new page is added, I verified it's using the ScrollView component to make it scrollable when more elements are added to the page.
  • I added unit tests for any new feature or bug fix in this PR to help automatically prevent regressions in this user flow.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.

Screenshots/Videos

Android: Native

White screen issue:

49880-android.mov
Android: mWeb Chrome

White screen issue:

49880-android-chrome.mov
iOS: Native

White screen issue:

49880.mov
iOS: mWeb Safari

White screen issue:

49880-safari.mov
MacOS: Chrome / Safari

Blank screen with magic link:

57359.mov
MacOS: Desktop

Relogin issue:

55681.59139.mov

Infinite loading issue:

59128.59184.mov
Unrelated console errors

These also happen on main.
Reporting them here to complete the PR checklist:

unrelated-errors

@LorenzoBloedow
Copy link
Contributor Author

LorenzoBloedow commented Jul 14, 2025

I planned on opening this draft PR in a day or two but, since some progress has already been made, I thought it'd be better to document it here.

First bug I found was an infinite loading screen, I haven't found why it only happens with useOnyx yet as I'm currently focusing on finding other bugs related to this change:

Before
translation-bug-before.mov
After
translation-bug-after.mov

What I can say about this bug though is that since the code wasn't using initialValue, when the stored value for ARE_TRANSLATIONS_LOADING was false, it wouldn't trigger an update when set to false again because, from Onyx's perspective, the value never changed. Thus it would stay in true forever, making the splash screen not go away. By using initialValue, Onyx now knows the initial value and can apply the update accordingly.

@LorenzoBloedow
Copy link
Contributor Author

Progress so far:

  • Checked white screen bug in both iOS and Desktop with a high traffic account, didn’t find anything.
  • Not able to reproduce app relogging after signing out.
  • Found this bug where the reports would load forever after relogging, I tried 3 different main approaches, but finally found one that works without any compromises:
Before fixing bug
infinite-loading-deeplink-before-test-desktop.mov
After fixing bug
infinite-loading-deeplink-after-test-desktop.mov
main branch
infinite-loading-deeplink-test-main-desktop.mov

@LorenzoBloedow
Copy link
Contributor Author

Explanation for the new NVP:

When you sign in with a deep link and then log out, we still have that same initial URL. Since after logging out we're switching from AuthScreens to PublicScreens, LogInWithShortLivedAuthTokenPage gets triggered because it sees that initial URL and thinks we're logging in for the first time, thus the NVP is a way to keep track of the last short lived auth token we logged in with (in a given environment) so that we can compare it to the current one and decide if it's an actual new login.

I tried resetting the initial URL, the problem is that RN doesn't support it.
I also tried wrapping Linking with a proxy that checks if the URL is the same as before, this creates a lot of other bugs though.

@LorenzoBloedow LorenzoBloedow marked this pull request as ready for review July 19, 2025 15:12
@LorenzoBloedow LorenzoBloedow requested a review from a team as a code owner July 19, 2025 15:12
@melvin-bot melvin-bot bot requested review from eVoloshchak and removed request for a team July 19, 2025 15:12
@melvin-bot
Copy link

melvin-bot bot commented Jul 19, 2025

@eVoloshchak Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button]

@LorenzoBloedow
Copy link
Contributor Author

@roryabraham @fabioh8010 Would love to get your eyes on this PR to make sure we don't get any regressions :)

@LorenzoBloedow
Copy link
Contributor Author

@eVoloshchak Can we please run the tests again? Looks like an unrelated test failed.

@eVoloshchak
Copy link
Contributor

@LorenzoBloedow, I can't manually re-trigger them, but a new commit will. Could you just pull the latest main, please? That should do the trick

@LorenzoBloedow
Copy link
Contributor Author

Got some unrelated lint errors from main but I think we can ignore those, will probably get fixed soon.

@LorenzoBloedow
Copy link
Contributor Author

@eVoloshchak Can you please test the hybrid build on your iPhone?
IPA files can't be installed on iOS simulators.

I did test the hybrid build on Android though and there's no animation but when I tested the actual production app on my physical device it also doesn't have a fade animation, so I'm guessing this is something that only happens on iOS.

@eVoloshchak
Copy link
Contributor

eVoloshchak commented Aug 21, 2025

Can you please test the hybrid build on your iPhone?

I cannot, unfortunately. The device has to be included in the team certificate, and mine isn't, as there is a limit on the number of devices

I did test this by building the app locally and comparing, I don't see a difference in animation locally

Testing if issues from the list in #66093 (comment) are resolved ✅

Screen.Recording.2025-08-21.at.18.00.01.mov

cc: @LorenzoBloedow

@LorenzoBloedow
Copy link
Contributor Author

@eVoloshchak Thanks for reviewing everything and catching that!

I reintroduced the token check I'd removed here (because we couldn't reproduce the relogin bug), I must've incorrectly tried to reproduce it then, probably not using two different accounts for the repro.

However, this time, instead of creating an onyx key for the last auth token, I simply used a regular variable, I think this is cleaner and less verbose, and seems to work perfectly since here we don't need the persistence of Onyx anyway.

I also made sure to create a test that simulates the relogin bug:

Here's the test before the fix (failing scenario):
tests-without-fix

And here's the test after the fix:
tests-with-fix

Also, here's a video of the non-repro after the latest fix:

relogin-fix.mov

@LorenzoBloedow
Copy link
Contributor Author

#55681 reproduced -

https://platform.applause.com/services/links/v1/external/27e75c257974a194e4eb92c9bcac9abb3f1ceb065cd64fc4cdcf6ee98e2c9a0b

#59139 reproduced -

https://platform.applause.com/services/links/v1/external/2ef4b17c6eabe3f90e57754a030e7ef7f658bd5cb433a7dd587267c27733550f

Adhoc build is outdated, this branch should already have the fixes for those.
Started a thread on Slack for this PR so we can hopefully finish this soon.

@eVoloshchak
Copy link
Contributor

#55681 reproduced -

#59139 reproduced -

Confirmed both of these are resolved

#59184 Blocked - unable to upgrade from another ad hoc build

Same, cannot update the dev version.
I wasn't able to reproduce this when updating the production Desktop app, so it looks like it was indeed resolved by #59188

@LorenzoBloedow
Copy link
Contributor Author

Just some documentation about the tests I wrote and the issues we know of...

it('should not remember the report path of the last deep link login after signing out and in again', async () => {

The test above makes sure we don't try to access the previous account's report after logging out and in with a deep link, therefore, it covers:

it('should not reuse the last deep link and log in again when signing out', async () => {

The test above makes sure we don't reuse the last deep link auth token after signing out. It covers:


About the 2 issues above:

  1. Haven't been able to repro.
  2. I don't think this is something we can write a test for as it's just a blank screen.
  3. Without a clear failing scenario there's no way to make sure the tests are correct.
  4. Seems like it'd be easy/fast to catch in QA.

@LorenzoBloedow
Copy link
Contributor Author

Tested all bugs, not able to reproduce any:

Relogin bug
Relogin.bug.mov
Not found page bug 1
Not.found.page.bug.1.mov
Not found page bug 2
Not.found.page.bug.2.mov
Infinite loading bug 1
Infinite.loading.bug.1.mov
Infinite loading bug 2
Infinite.loading.bug.2.mov
Blank screen with magic link bug
Blank.screen.with.magic.link.bug.mov
iOS blank screen bug
iOS.blank.screen.bug.mov

@roryabraham
Copy link
Contributor

I see tsc failed, but it appears to have been due to an unrelated issue

@eVoloshchak
Copy link
Contributor

@LorenzoBloedow, could you resolve the conflicts please?

@eVoloshchak
Copy link
Contributor

eVoloshchak commented Aug 27, 2025

Reviewer Checklist

  • I have verified the author checklist is complete (all boxes are checked off).
  • I verified the correct issue is linked in the ### Fixed Issues section above
  • I verified testing steps are clear and they cover the changes made in this PR
    • I verified the steps for local testing are in the Tests section
    • I verified the steps for Staging and/or Production testing are in the QA steps section
    • I verified the steps cover any possible failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
  • I checked that screenshots or videos are included for tests on all platforms
  • I included screenshots or videos for tests on all platforms
  • I verified that the composer does not automatically focus or open the keyboard on mobile unless explicitly intended. This includes checking that returning the app from the background does not unexpectedly open the keyboard.
  • I verified tests pass on all platforms & I tested again on:
    • Android: HybridApp
    • Android: mWeb Chrome
    • iOS: HybridApp
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
    • MacOS: Desktop
  • If there are any errors in the console that are unrelated to this PR, I either fixed them (preferred) or linked to where I reported them in Slack
  • I verified there are no new alerts related to the canBeMissing param for useOnyx
  • I verified proper code patterns were followed (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick).
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text shown in the product is localized by adding it to src/languages/* files and using the translation method
    • I verified all numbers, amounts, dates and phone numbers shown in the product are using the localization methods
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named "index.js". All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I verified that this PR follows the guidelines as stated in the Review Guidelines
  • I verified other components that can be impacted by these changes have been tested, and I retested again (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar have been tested & I retested again)
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.ts or at the top of the file that uses the constant) are defined as such
  • If a new component is created I verified that:
    • A similar component doesn't exist in the codebase
    • All props are defined accurately and each prop has a /** comment above it */
    • The file is named correctly
    • The component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
    • The only data being stored in the state is data necessary for rendering and nothing else
    • For Class Components, any internal methods passed to components event handlers are bound to this properly so there are no scoping issues (i.e. for onClick={this.submit} the method this.submit should be bound to this in the constructor)
    • Any internal methods bound to this are necessary to be bound (i.e. avoid this.submit = this.submit.bind(this); if this.submit is never passed to a component event handler like onClick)
    • All JSX used for rendering exists in the render method
    • The component has the minimum amount of code necessary for its purpose, and it is broken down into smaller components in order to separate concerns and functions
  • If any new file was added I verified that:
    • The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label and/or tagged @Expensify/design so the design team can review the changes.
  • If a new page is added, I verified it's using the ScrollView component to make it scrollable when more elements are added to the page.
  • For any bug fix or new feature in this PR, I verified that sufficient unit tests are included to prevent regressions in this flow.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.
  • I have checked off every checkbox in the PR reviewer checklist, including those that don't apply to this PR.

Screenshots/Videos

Android: HybridApp
Screen.Recording.2025-08-27.at.18.55.45.mov
Android: mWeb Chrome Not found page bug 2, Infinite loading bug 2:
Screen.Recording.2025-08-27.at.19.00.10.mov

Blank screen with magic link bug:

Screen.Recording.2025-08-27.at.19.05.29.mov
iOS: HybridApp
Screen.Recording.2025-08-27.at.19.41.49.mov
iOS: mWeb Safari Not found page bug 2, Infinite loading bug 2:
Screen.Recording.2025-08-27.at.19.11.34.mov

Blank screen with magic link bug:

Screen.Recording.2025-08-27.at.19.13.49.mov
MacOS: Chrome / Safari Not found page bug 2:
Screen.Recording.2025-08-27.at.18.39.49.mov

Infinite loading bug 2:

Screen.Recording.2025-08-27.at.18.42.22.mov

Blank screen with magic link bug:

Screen.Recording.2025-08-27.at.18.46.27.mov
MacOS: Desktop Relogin bug:
Screen.Recording.2025-08-27.at.18.30.07.mov

Not found page bug 1:

Screen.Recording.2025-08-27.at.18.32.03.mov

Not found page bug 2:

Screen.Recording.2025-08-27.at.18.34.58.mov

Infinite loading bug 1-2:

Screen.Recording.2025-08-27.at.18.36.41.mov

Copy link
Contributor

@eVoloshchak eVoloshchak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@melvin-bot melvin-bot bot requested a review from roryabraham August 27, 2025 17:45
@roryabraham roryabraham merged commit 189b876 into Expensify:main Aug 27, 2025
24 of 25 checks passed
@OSBotify
Copy link
Contributor

✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release.

@OSBotify
Copy link
Contributor

🚀 Deployed to staging by https://github.com/roryabraham in version: 9.2.0-0 🚀

platform result
🖥 desktop 🖥 success ✅
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 success ✅

@OSBotify
Copy link
Contributor

OSBotify commented Sep 2, 2025

🚀 Deployed to production by https://github.com/arosiclair in version: 9.2.0-5 🚀

platform result
🖥 desktop 🖥 success ✅
🕸 web 🕸 failure ❌
🤖 android 🤖 success ✅
🍎 iOS 🍎 success ✅

@OSBotify
Copy link
Contributor

OSBotify commented Sep 2, 2025

🚀 Deployed to production by https://github.com/arosiclair in version: 9.2.0-5 🚀

platform result
🖥 desktop 🖥 success ✅
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 success ✅

@roryabraham
Copy link
Contributor

Wooooooo! Deployed to prod 🚀

Great job @LorenzoBloedow @eVoloshchak

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants