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

Connection Lost on Safari #7132

Open
ahmed-shahid-confiz opened this issue Mar 17, 2023 · 26 comments
Open

Connection Lost on Safari #7132

ahmed-shahid-confiz opened this issue Mar 17, 2023 · 26 comments

Comments

@ahmed-shahid-confiz
Copy link

[REQUIRED] Describe your environment

  • Operating System version: iOS 16+
  • Browser version: Safari 16+
  • Firebase SDK version: 9.9.2
  • Firebase Product: realtime database

[REQUIRED] Describe the problem

Steps to reproduce:

  1. Use the javascript sdk in a react app in PWA mode in an iphone with iOS 16+.
  2. Use the onValue method to observe for changes on one component.
  3. Open the component that uses onValue.
  4. Close the component.
  5. Put the app in background.
  6. Interact with other apps on the phone for a few minutes.
  7. Open the component again that uses the onValue method.

The onValue method never returns the snapshot and does not throw any error either.

I have tried managing online presence as mentioned in the documentation here.

The onValue method does not return for the ".info/connected" node nor does it throw any error.

It starts working once the app is killed and relaunched. But, we cannot communicate to users to kill the app whenever they see an issue such as this. Can anybody help here?

I reached out to support and this was their final response which is why I opened the issue here on GitHub:
image

@google-oss-bot
Copy link
Contributor

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

@ahmed-shahid-confiz
Copy link
Author

Any update here?

@ahmed-shahid-confiz
Copy link
Author

Any update here?

@DellaBitta
Copy link
Contributor

Hi @ahmed-shahid-confiz,

Could you provide a minimal reproducible test case so that we can better understand and reproduce your code usage? Thanks!

@ahmed-shahid-confiz
Copy link
Author

Hi @DellaBitta,
I have attached the steps already. Let me restate them here:

  1. Use the javascript sdk in a react app in PWA mode in an iphone with iOS 16+.
  2. Use the onValue method to observe for changes on one component.
  3. Open the component that uses onValue.
  4. Close the component.
  5. Put the app in background.
  6. Interact with other apps on the phone for a few minutes while keeping the PWA in background.
  7. Open the component again that uses the onValue method.
  8. The method will never return nor will it throw an error.

@DellaBitta
Copy link
Contributor

Hi @ahmed-shahid-confiz,

Thanks for clarifying the steps. I'm also seeking the code snippet of when you register the Database listener. There are some nuances there particularly when it comes to React components. For instance, you might use the onEffect function (as described here) or perhaps not?

I don't think we'd need your whole app, but could you please post the code that demonstrates how you've set up the listener in your component?

Also, to clarify:

The method will never return nor will it throw an error.

Which method? The callback registered with onValue? Is it invoked but it's not returning, or is it not being invoked at all?

Finally, have you successfully tested this on other browsers, and if so which ones?

Thank you!

@ahmed-shahid-confiz
Copy link
Author

Hi @DellaBitta,

We use a service to initialize firebase. An instance of the service is exported in the same file.

Here is the code:

class FirebaseService {
    private app: FirebaseApp;
    private db: Database;
    private auth: Auth;

    constructor() {
        isSupported().then((supported) => {
            if (supported) {
                this.app = initializeApp(config.firebase.courses);
                this.auth = getAuth();
                if (this.app) {
                    this.db = getDatabase(this.app);
                    this.analytics = getAnalytics(this.app);
                }
            }
        });
    }

    async observeStats(
        param1: string,
        param2: string,
        onObserve: (stats: Stats) => void,
    ) {
        const dbRef = ref(
            this.db,
            `${path}`,
        );

        onValue(dbRef, (snapshot) => {
            onObserve(snapshot.val());
        });
    }
}
export const firebaseService = new FirebaseService();

This service is used through a hook. Code for that is:

export const useStats = (param1: string, param2: string) => {
    const [observedStats, setObservedStats] =
        useState<Stats>(null);

    if (param1 && param2) {
        courseFirebaseService.observeStepStats(param1, param2, (stats) => {
            if (!isEqual(stats, observedStepStats)) {
                setObservedStepStats(stats);
            }
        });
    }

    return { observedStepStats };
};

This hooks is then used in a component in this form:

const { observedStepStats } = useStats(param1, param2);

Also, we were recently experimenting with the get method and found that the issue is reproduced with that method as well.
Here are the steps with the get method:

  1. Use the get method in one component of the application.
  2. Show a snackbar whenever the get method returns the callback (snapshot or error).
  3. Open the PWA.
  4. Navigate to the component with the get method.
  5. The snackbar appears.
  6. Put the PWA in background for a few seconds.
  7. Navigate to the PWA from recent apps.
  8. Repeat steps 4 to 7 a couple of times.
  9. The method stops returning.

With respect to your question, I have mentioned the onValue method. The callback for the onValue has two parameters, the snapshot or the error. When this issue occurs, nothing is received in the callback no matter how long you wait for it.

Other browsers

We have tested on Google Chrome and Samsung Internet and found that the issue does not exist over there.

@ahmed-shahid-confiz
Copy link
Author

Any update here, @DellaBitta ?

@piv0vip
Copy link

piv0vip commented Jun 27, 2023

I have the same issue on Vue 2.7, firebase-js sdk 9.22.2, cordova, iOS 16+
onValue silently "disappearing" without any exceptions and messages
also "disappearing" onAuthStateChanged() listener, causing users to lose the ability to log in
the steps to reproduce are exactly the same as @ahmed-shahid-confiz described above

@ahmed-shahid-confiz
Copy link
Author

Any update here, @DellaBitta?

@HazzMan2409
Copy link

HazzMan2409 commented Jul 4, 2023

I'm seeing this as well. For me I can see the issue straight away when I switch off my wifi and start using cellular data on my iPhone.

I have a standard setup for connecting to the database (not within a service worker) and listening to onValue(). Also, the issue has nothing to do with React as it occurs without it.

@HazzMan2409
Copy link

HazzMan2409 commented Jul 8, 2023

After doing a bit more digging I found this WebKit bug which explains the behaviour I'm seeing https://bugs.webkit.org/show_bug.cgi?id=247943. If you turn off the NSURLSession WebSocket experimental WebKit feature does this bug go away?

@ahmed-shahid-confiz
Copy link
Author

Any update here @DellaBitta?

@jbalidiong
Copy link
Contributor

Hi everyone, thanks for the detailed steps on replicating the behavior and some additional information about the issue. I was able to replicate it and raised it to our Firebase Realtime Database team. Let me check what we can do for this issue or bring someone here that can provide more context about it. I’ll update this thread if I have any information to share.

@ahmed-shahid-confiz
Copy link
Author

Any update here guys?

@lazmeister
Copy link

we have somewhat similar issues in AngularFire, even if I use the firebase library the value is not received true/false for a connection status on iOS but meanwhile every other OS and browser seems to work fine.

@ahmed-shahid-confiz
Copy link
Author

Any update here @DellaBitta, @jbalidiong ?

@ahmed-shahid-confiz
Copy link
Author

Any update here @DellaBitta , @jbalidiong ?

@DellaBitta
Copy link
Contributor

Hi @ahmed-shahid-confiz,

Someone from the RTDB team is looking into this issue.

@ahmed-shahid-confiz
Copy link
Author

Hi @maneesht,

We are working on another similar feature but have planned to use Firestore instead. Is there any chance that such an issue might exist there as well?

@maneesht
Copy link
Contributor

Hi @ahmed-shahid-confiz - I don't believe the same issue should occur using Firestore, as they don't use websockets, and instead use webchannel. Tagging @dconeybe from the Firestore team to add any additional clarifications.

Also, I'm not sure how relevant the listed webkit bug is to the issue above, as it seems more related to losing connectivity. Do you have any connectivity issues when running the steps you mentioned above?

@ahmed-shahid-confiz
Copy link
Author

Hi @maneesht,

I dont think the issue is related to connectivity because we have tried calling cloud functions via the sdk while this issue had occurred in the app. The cloud functions work as desired. Is there anything else I need to check in this respect?

@dconeybe
Copy link
Contributor

Hi @ahmed-shahid-confiz - I don't believe the same issue should occur using Firestore, as they don't use websockets, and instead use webchannel. Tagging @dconeybe from the Firestore team to add any additional clarifications.

I have not heard of issues of this nature on Firestore. I can definitely confirm that Firestore does not use websockets, but rather uses webchannel, a Google-authored alternative to websockets (link).

@lazmeister Have you reported your bug to Firestore? If so, please provide the issue link. If not, feel free to open a new issue if this is still a problem for you. If you do have an issue, it is very unlikely to be related to this Realtime Database issue since the code bases for Firestore and Realtime Database are completely separate.

@lazmeister
Copy link

@dconeybe When I have some time I will create a repo to show the issue. We are definitely having issues with offline/online detection period on iOS but we are also using AngularFire so that's a whole other problem since they are not on the latest firebase

@maisasb
Copy link

maisasb commented Nov 9, 2023

@lazmeister I'm facing similar issue on Firestore after migrate version 8 to 10. Just on OS: iOS 16 or Safari 16. iOS 17 works fine.
When user reload page or put in background for while, the connection stop and start to receive a lot of Load failed errors

@matt-wormley
Copy link

matt-wormley commented Sep 13, 2024

I'm facing this I think - iOS16 with latest React and Firebase sdk. When it happens for me it affects all tabs. Refreshing the tab does not solve it and new tabs face the problem as well with onValue never firing success or failure. When it starts working in one tab it then works in all tabs. I believe I was able to have it operate correctly in incognito tabs while the issue reproduced in normal tabs which was interesting. I was able to trigger this issue while using my phone around the city but never in a controlled environment.

Is the workaround here to move to firestore? Is there another issue tracking this?

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

No branches or pull requests