Fix: Incorrect unread actions counts#5302
Conversation
Include the existing maxSequenceNumber in the logic as we might already have a higher max sequence number
| const currentMaxSequenceNumber = reportMaxSequenceNumbers[reportID] || 0; | ||
| if (maxSequenceNumber > currentMaxSequenceNumber) { | ||
| Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, {maxSequenceNumber}); | ||
| } |
There was a problem hiding this comment.
So, this change makes sense to me on the one hand because I'd expect things to get very screwed up when we call Report_GetHistory with paginated results. Since what comes back can be historical it possibly won't be the "max sequence number we have" so it makes sense to compare it with some previously fetched result. Great job identifying that.
On the other hand, it really feels like if Report_GetHistory can return some set of items that may or may not contain the "maxSequenceNumber" then maybe we should not be relying on Report_GetHistory at all to derive the "maxSequenceNumber".
It feels like it could be possible (although I haven't verified this) that we might:
- have no local
reportMaxSequenceNumbers[reportID]for a given report - then we get some older paginated history from this API
- then we would set the max to the highest returned (which is possibly not the "true max")
This still feels wrong to me and I wanted to propose that maybe instead of setting the max when fetching history we should always use the reportSummaryList to do it. Hard to see from this without inspecting network requests, but we have a reportActionCount that is returned when we get the reportSummaryList here:
App/src/libs/actions/Report.js
Line 188 in 8d7b62f
That said, I don't know if it's a perfect solution since we'd have to add a network request next to some places where we are fetching the report history. Gonna tag in @tgolen for his opinion on this.
There was a problem hiding this comment.
Great observations @marcaaron
From my experience paging API's would usually respond with the total amount of items anytime you fetch a page
If that's added to the response we can just use it here
It feels like it could be possible (although I haven't verified this) that we might:
- have no local
reportMaxSequenceNumbers[reportID]for a given report- then we get some older paginated history from this API
I thought of that as well and did an investigation - it doesn't look likely, at least I couldn't find a way. fetchActions is called (with offset) only through ReportActionView paging and here:
App/src/libs/actions/Report.js
Lines 994 to 997 in 3b9a54f
Since the above code runs in a timer I think we'll have a reportActionCount as you've pointed out is fetched with the reportSummaryList
The other time would be when a new report comes from pusher, but this also triggers a call that should fetch the correct data
There was a problem hiding this comment.
I wanted to propose that maybe instead of setting the max when fetching history we should always use the reportSummaryList to do it
As I was reading through the comments, this is exactly the solution that came to my mind.
we'd have to add a network request next to some places where we are fetching the report history
This is the part that I'm not too sure about. Is this really necessary? I am just trying to think of any place where we:
- Haven't called reportSummaryList
- Are fetching the report history
- Need the max sequence number
From my experience paging API's would usually respond with the total amount of items anytime you fetch a page
I also agree with Kidroca here, that it's very typical that pagination APIs will return the total number of records along with the paginated results, so I'd be fine with adding it here too.
There was a problem hiding this comment.
Seems we're calling fetchChatReportsByIDs which in the end updates reportActionCount for these cases:
- during init/refresh (for all reports)
- for new report we learn about through pusher (receiving an action from a report we don't have)
- when we're back online (for all reports)
So it's totally possible we don't need to update max count when we fetch actions, but I haven't tested.
I think we're missing the case where we resume a suspended app e.g.
AppState.addEventListener('change', this.onVisibilityChange);There's no code that will fetch all reports when we bring focus back to the app, though it might not be necessary. There's one listener in ReportActionsView that will refetch the current report (wrong)
AFAIK the pusher connection is dropped when the app is suspended for more than 5-10 minutes (ios), so we might have a problem there
There was a problem hiding this comment.
Is this possible: we've lost connection to pusher, so we miss some new messages, when we open a chat we always fetch the latest (no offset) so we'll fetch the new messages through http, but they will not update the maxSequenceNumber if we remove the logic
There was a problem hiding this comment.
This is the part that I'm not too sure about. Is this really necessary?
We might be able to get rid of it entirely. Tbh, I am missing some context for why we started setting the maxSequenceNumber when fetching the history in the first place. I think it was added in the POC stages here.
Maybe we thought fetching the actions was a good place to poll for the max sequence number and update the unreads? And since we could guarantee that it would always include the highest was safe/convenient to do this here?
So, it sounds like our current options are:
- Hold this PR on a backend change to return a
reportActionCountwithReport_GetHistory - Investigate whether we can stop updating the
maxSequenceNumberhere entirely and no backend change would be necessary - Merge this current change temporarily then follow up and do 2 and possibly 1 if we decide that we do want to set the
maxSequenceNumberhere.
I'm 👍 on doing 3 as long as we do a follow up after.
There was a problem hiding this comment.
IMO we should continue updating the maxSequenceNumber in fetchActions - in case it fetches (new) actions we don't have locally. I think it can still happen sometime.
There was a problem hiding this comment.
We're using fetchActions as a "message source", we're using Pusher as a "message source", when we receive new messages through any of these sources we should update the maxSequenceNumber. Pusher handles it in a different way since it would only receive new messages
Setting `maxSequenceNumber` during `fetchActions` is no longer necessary
I did an investigation regarding 2) We're calling
Overall it looks safe to drop setting of
I've pushed an update that removes |
tgolen
left a comment
There was a problem hiding this comment.
Thanks for the investigation! I agree with your conclusions and hopefully this is a step forward!
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🚀 Deployed to staging by @marcaaron in version: 1.1.2-9 🚀
|
Details
Include the existing
maxSequenceNumberin the logic as we might already have a higher valueFixed Issues
$ #4273
Tests
Note: the bug might have already caused to have incorrect unread notifications count stored for your account on the backed.
To ensure you're starting from a clean slate:
For all platforms
stagingto see them recreate the bugQA Steps
Follow the same tests steps as above. You can also try the rest of the discovered ways to recreate this issue - here #4273 (comment) and here #4273 (comment). These steps should no longer produce unread messages
Tested On
Screenshots
Web
Screen.Recording.2021-09-17.at.19.40.03.mov
Web: before: #4273 (comment)
Mobile Web
Screen.Recording.2021-09-17.at.19.36.38.mov
Desktop
Screen.Recording.2021-09-17.at.18.52.48.mov
Desktop before: #4273 (comment)
iOS
Screen.Recording.2021-09-17.at.19.24.15.mov
iOS before: #4273 (comment)
Android
Android.Emulator.-.Pixel_2_API_29_5554.2021-09-16.21-35-06.mp4
Android before: #4273 (comment)