Skip to content
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

Viewing Likes tab/page for an account/profile/user with no liked posts causes infinite spinner/loop XHR [web] #4879

Open
surfdude29 opened this issue Aug 5, 2024 · 13 comments · May be fixed by #7770
Labels
bug Something isn't working

Comments

@surfdude29
Copy link
Contributor

surfdude29 commented Aug 5, 2024

Describe the bug

When you're logged into an account which hasn't liked any posts yet and you view the Likes tab on web, it loads infinitely.

To Reproduce

Steps to reproduce the behavior:

  1. On bsky.app log into an account which hasn't liked any posts yet (I created a temporary alt to make the screen recording below).
  2. View the Likes tab on the account's profile.
  3. The spinner is displayed infinitely.

Expected behavior

The spinner should stop and the No posts yet. screen should be displayed.

Screenshots

RPReplay_Final1722889075.mov

Details

  • Platform: iPadOS Safari and Brave on Ubuntu
  • Platform version: 16.6.1
  • App version: 1.92.1

EDIT: Updated description to make clearer and reflect that this still occurs on 1.92.1 on web.

@surfdude29 surfdude29 added the bug Something isn't working label Aug 5, 2024
@surfdude29
Copy link
Contributor Author

surfdude29 commented Aug 5, 2024

I noticed that the infinite spinner also shows up if you've only liked a few posts and you scroll down and reach the end of your likes.

@heikadog
Copy link

heikadog commented Aug 6, 2024

This also shows up on the regular Bluesky web app.

@haileyok
Copy link
Contributor

haileyok commented Aug 6, 2024

I cannot reproduce this right now. There was momentarily an appview bug that we fixed shortly after it got deployed, so can you try again?

@heikadog If you're seeing this currently it is likely a separate issue. Would be good if you could record a video!

@surfdude29
Copy link
Contributor Author

This also shows up on the regular Bluesky web app.

Thanks for pointing this out 🙏

I've corrected the description.

@surfdude29
Copy link
Contributor Author

I cannot reproduce this right now. There was momentarily an appview bug that we fixed shortly after it got deployed, so can you try again?

I can still reproduce this on bsky.app in Safari (iPadOS 16.6.1) but not in 1.89 of the iOS/iPadOS app.

@haileyok
Copy link
Contributor

haileyok commented Aug 6, 2024

Wait, does this only happen on iPad? Also @heikadog

I cannot repro on bsky.app with Safari at least.

@surfdude29
Copy link
Contributor Author

surfdude29 commented Aug 6, 2024

I can reproduce this in:

  • Safari on iPhone 7 running iOS 15.8.3
  • Safari on iPad (9th generation) running iPadOS 16.6.1
  • Brave 1.68.134 Chromium: 127.0.6533.88 (Official Build) (64-bit) on Ubuntu 20.04.6 LTS
  • Chrome 127.0.6533.99 (Official Build) (64-bit) on Ubuntu 20.04.6 LTS
  • Firefox 128.0 (64-bit) on Ubuntu 20.04.6 LTS

Screen recording from my iPhone:

RPReplay_Final1722973140.mp4

@haileyok
Copy link
Contributor

haileyok commented Aug 6, 2024

Ah, missed that it was specifically the likes tab. Thanks.

@nucleartux
Copy link
Contributor

If anyone is interested, I did a quick investigation.
I suspect a bug on the ATProto side because, for some reason, app.bsky.feed.getActorLikes returns a cursor even if the feed is empty.
Unfortunately, I was unable to reproduce it with a local ATProto instance. To be more specific, I know such a response is possible if liked posts are deleted, but this is a different case.

@surfdude29 surfdude29 changed the title Viewing Likes tab for an account with no posts liked causes infinite spinner Viewing Likes tab/page for an account with no liked posts causes infinite spinner Oct 19, 2024
@surfdude29 surfdude29 changed the title Viewing Likes tab/page for an account with no liked posts causes infinite spinner Viewing Likes tab/page for an account with no liked posts causes infinite spinner [web] Oct 20, 2024
@surfdude29 surfdude29 changed the title Viewing Likes tab/page for an account with no liked posts causes infinite spinner [web] Viewing Likes tab/page for an account/profile/user with no liked posts causes infinite spinner/loop XHR [web] Oct 20, 2024
@roni-castro
Copy link

roni-castro commented Nov 12, 2024

Scenarios to Reproduce the Error (tested on version 1.94.0)

Scenario for 0 Likes:

  1. Create a new account in the app and log in.
  2. Tap on the Profile tab.
  3. Tap on the Likes tab.
  4. You will see the spinner being rendered 50 times

Scenario for Few Likes:

  1. Create a new account and log in to the app.
  2. Like a few posts (e.g., 2 posts).
  3. Tap on the Profile tab.
  4. Tap on the Likes tab.
  5. You will see the spinner being rendered infinite times

It seems that the Likes tab is facing multiple issues:

Issue 1

The onEndReached function is being triggered multiple times when there are very few likes. This results in an infinite loop of requests to the API until the user hits the API rate limit.

Note: The RN debugger struggles with handling infinite loops, so you can confirm this behavior by adding console.log('fetchNextPage') and observing that fetchNextPage is being called repeatedly for the scenario with few likes.

Demo:

on_end_reached_called_multiple_times.mp4

Issue 2

When the list does not have at least MIN_POSTS items, there's a useEffect that runs the logic to fetch the next page using query.fetchNextPage() up to 50 times. This happens every time any property of the query object (data, fetchStatus, isFetching, isFetchingNextPage, etc.) changes.

Issue 3

The API returns an invalid cursor when there are no likes or just a few likes or the last page for app.bsky.feed.getActorLikes.

  • Expected behavior: When the last page has NO likes/feed, the API should return {"feed": []}.
  • Current behavior: It instead returns an invalid cursor: {"feed": [], "cursor": "3l3ejwggbzz22"}.

This invalid cursor leads to continuous triggering of the above useEffect because the query object (returned by useInfiniteQuery) changes, causing the effect to re-run.

Scenarios:

  • 0 likes: Results in exactly 50 API requests.
50_requests_done_on_empty_list.mp4
  • Few likes: Causes an infinite number of requests until the API rate limit is reached, likely leading to an error for the user.
infinite_requests_when_there_are_few_items.mp4
  • Last page: Causes an infinite number of requests
infinite_loop_last_page.mp4

Potential Workaround

A fix on the backend side would be to stop returning an invalid cursor when the API returns an empty feed: []. However, even with that fix, there may still be concurrency issues due to the problems described in Issues 1 and 2, but at least not visible to the app's user.

It was used in the examples below, Proxyman to intercept the api request and change it to return a valid response when feed is empty and an invalid cursor is returned.

  • Stop returning an invalid cursor for empty feeds (0 likes):
solution-zero_items_dont_return_cursor.mp4
  • Stop returning an invalid cursor when there are only a few likes on a specific page:
solution-keep_cursor_for_feed_not_empty_and_remove_for_feed_empty.mp4

@fdemir
Copy link

fdemir commented Nov 24, 2024

issue still exists on the latest version

@kidonng
Copy link

kidonng commented Dec 6, 2024

An easy mitigation may be just reducing the failsafe limit added in c6f9cfc (#4863) (currently 50).

@Doeke
Copy link

Doeke commented Jan 22, 2025

Is this the same issue as not being able to load more than 32 liked posts on app or with api? Even if I use the api app.bsky.feed.getActorLikes it just returns cursors with empty feed lists once it gets past the first 32, I cannot fetch older likes at all

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants