Skip to content

Initialization takes 30 seconds with the error "Uncaught TypeError: u[v] is not a function" in Chrome for mobile devices #711

@yosipy

Description

@yosipy

Describe the bug

Initialization may take 30 seconds with the error "Uncaught TypeError: u[v] is not a function".
It doesn't happen every time, but at least once every few times.
I have confirmed that this issue occurs on Chrome for mobile devices such as Android devices. (I also reproduced it with the emulator of Chrome's developer tools for PC.) This did not occur on Chrome for PC.

I have created three examples to illustrate this problem and they are shown below. Also, the repository is https://github.com/yosipy/yosi_sandbox/tree/main/20240128_next_firebase_auth_example .

Example using onAuthStateChanged

https://github.com/yosipy/yosi_sandbox/blob/main/20240128_next_firebase_auth_example/pages/sample_on_auth_state_changed.tsx

  1. Start up the example Next.js app server in this repository.
  2. Add the following code to pages/sample_on_auth_state_changed.tsx.
import { FC, useEffect } from "react";

import { useUser, withUser } from "next-firebase-auth";
import { getAuth } from "firebase/auth";

const Index: FC = () => {
  const currenUser = useUser();
  console.log(
    `currenUser.clientInitialized: ${
      currenUser.clientInitialized
    } (${new Date()})`
  );

  const auth = getAuth();
  useEffect(() => {
    const unsubscribeOnAuthStateChanged = auth.onAuthStateChanged(
      (onAuthStateChangedUser) => {
        console.log(
          `onAuthStateChangedUser: ${onAuthStateChangedUser} (${new Date()})`
        );
      },
      (error) => {
        console.error("useFirebaseAuth:", error);
      }
    );

    return () => {
      unsubscribeOnAuthStateChanged();
    };
  }, []);

  return (
    <>
      <p>onAuthStateChanged</p>
    </>
  );
};

export default withUser()(Index);
  1. Open your Chrome browser and use developer tools to view it as a mobile site (Ctrl + Shift + M).
    This icon → image
  2. Visit the page several times. I think it's better to run it in incognito mode to reduce the impact of browser-side cache. I think super reload is better (Ctrl + Shift + R).

Below is the log when the problem occurred.

Download the React DevTools for a better development experience: https://reactjs.org/link/react-devtools
initAuth.js:24 next-firebase-auth [init] Setting config with provided value: {debug: true, loginAPIEndpoint: '/api/login', logoutAPIEndpoint: '/api/logout', authPageURL: ƒ, appPageURL: ƒ, …}
initAuth.js:24 next-firebase-auth [init] Initialized the Firebase JS SDK.
sample_on_auth_state_changed.tsx:39 next-firebase-auth [withUser] Calling "withUser".
websocket.js:48 [HMR] connected
index.browser.js:2 next-firebase-auth [withUser] Set user to: {id: null, email: null, emailVerified: false, tenantId: null, phoneNumber: null, …}
sample_on_auth_state_changed.tsx:8 currenUser.clientInitialized: false (Mon Jan 29 2024 10:41:51 GMT+0900 (日本標準時))
api.js?onload=__iframefcb590529:29 Uncaught TypeError: u[v] is not a function
    at Q.<computed> [as loaded_0] (api.js?onload=__iframefcb590529:29:145)
    at cb=gapi.loaded_0?le=scs:1:6
Q.<computed> @ api.js?onload=__iframefcb590529:29
(anonymous) @ cb=gapi.loaded_0?le=scs:1
index.browser.js:2 next-firebase-auth [withUser] The Firebase ID token changed. New Firebase user: null
index.browser.js:2 next-firebase-auth [withUser] Calling the logout endpoint.
index.browser.js:2 next-firebase-auth [withUser] Set user to: {id: null, email: null, emailVerified: false, tenantId: null, phoneNumber: null, …}
sample_on_auth_state_changed.tsx:8 currenUser.clientInitialized: true (Mon Jan 29 2024 10:41:51 GMT+0900 (日本標準時))
index.browser.js:2 next-firebase-auth [withUser] Completed the auth API request.
index.browser.js:2 next-firebase-auth [withUser] Set user to: {id: null, email: null, emailVerified: false, tenantId: null, phoneNumber: null, …}
sample_on_auth_state_changed.tsx:8 currenUser.clientInitialized: true (Mon Jan 29 2024 10:41:51 GMT+0900 (日本標準時))
sample_on_auth_state_changed.tsx:18 onAuthStateChangedUser: null (Mon Jan 29 2024 10:42:21 GMT+0900 (日本標準時))

The access occurred at approximately 10:41:51, but the onAuthStateChangedUser callback function was executed at 10:42:21.
It took about 30 seconds.

Example sign-in page

https://github.com/yosipy/yosi_sandbox/blob/main/20240128_next_firebase_auth_example/pages/sample_auth.tsx

  1. Start up the example Next.js app server in this repository.
  2. Add the following code to pages/sample_auth.tsx.
import React from "react";
import { withUser } from "next-firebase-auth";
import FirebaseAuth from "../components/FirebaseAuth";

const styles = {
  content: {
    padding: `8px 32px`,
  },
  textContainer: {
    display: "flex",
    justifyContent: "center",
    margin: 16,
  },
};

const Auth = () => (
  <div style={styles.content}>
    <h3>Sign in</h3>
    <div style={styles.textContainer}>
      <p>
        This auth page is <b>static</b>. It will redirect on the client side if
        the user is already authenticated.
      </p>
    </div>
    <div>
      <FirebaseAuth />
    </div>
  </div>
);

export default withUser()(Auth);

This is a modification of pages/auth.js.
3. Modify signInOptions in components/FirebaseAuth.js to allow signing in with a Google account.

  signInOptions: [
    {
      provider: GoogleAuthProvider.PROVIDER_ID,
      customParameters: {
        prompt: "select_account",
      },
    },
  ],
  1. Open your Chrome browser and use developer tools to view it as a mobile site (Ctrl + Shift + M).
    This icon → image
  2. Visit the page several times. I think it's better to run it in incognito mode to reduce the impact of browser-side cache. I think super reload is better (Ctrl + Shift + R).

It will take about 30 seconds for the button that says Sign in with Google to appear.

image →Translation 30 seconds later→ image

Example of retrieving data from Firestore

https://github.com/yosipy/yosi_sandbox/blob/main/20240128_next_firebase_auth_example/pages/sample_firestore1.tsx

  1. Start up the example Next.js app server in this repository.
  2. Add the following code to pages/sample_firestore1.tsx.
import { FC, useEffect, useState } from "react";

import {
  collection,
  getDocs,
  getFirestore,
  limit,
  orderBy,
  query,
  where,
} from "firebase/firestore";
import { withUser } from "next-firebase-auth";
import { getAuth } from "firebase/auth";

const Index: FC = () => {
  const [articleIds, setArticleIds] = useState<string[]>([]);

  const db = getFirestore();

  const fetch = async () => {
    console.log("Fetch start: " + new Date());

    const articlesSnap = await getDocs(
      query(
        collection(db, "articles"),
        where("public", "==", true),
        orderBy("createdAt", "desc"),
        limit(20)
      )
    );
    const fetchedArticleIds = articlesSnap.docs.map((doc) => doc.id);
    setArticleIds(fetchedArticleIds);

    console.log("Fetch end: " + new Date());
  };

  const auth = getAuth();
  useEffect(() => {
    fetch();
  }, []);

  return (
    <>
      <p>articleIds</p>
      {articleIds.map((id) => (
        <div key={id}>{id}</div>
      ))}
    </>
  );
};

export default withUser()(Index);
  1. Change Firestore's security rules to allow data to be retrieved from the articles collection.
  2. Open your Chrome browser and use developer tools to view it as a mobile site (Ctrl + Shift + M).
    This icon → image
  3. Visit the page several times. I think it's better to run it in incognito mode to reduce the impact of browser-side cache. I think super reload is better (Ctrl + Shift + R).

The log will look like this:

Download the React DevTools for a better development experience: https://reactjs.org/link/react-devtools
initAuth.js:24 next-firebase-auth [init] Setting config with provided value: {debug: true, loginAPIEndpoint: '/api/login', logoutAPIEndpoint: '/api/logout', authPageURL: ƒ, appPageURL: ƒ, …}
initAuth.js:24 next-firebase-auth [init] Initialized the Firebase JS SDK.
sample_firestore1.tsx:52 next-firebase-auth [withUser] Calling "withUser".
websocket.js:48 [HMR] connected
index.browser.js:2 next-firebase-auth [withUser] Set user to: {id: null, email: null, emailVerified: false, tenantId: null, phoneNumber: null, …}
sample_firestore1.tsx:21 Fetch start: Mon Jan 29 2024 10:43:44 GMT+0900 (日本標準時)
api.js?onload=__iframefcb846299:29 Uncaught TypeError: u[v] is not a function
    at Q.<computed> [as loaded_0] (api.js?onload=__iframefcb846299:29:145)
    at cb=gapi.loaded_0?le=scs:1:6
Q.<computed> @ api.js?onload=__iframefcb846299:29
(anonymous) @ cb=gapi.loaded_0?le=scs:1
index.browser.js:2 next-firebase-auth [withUser] The Firebase ID token changed. New Firebase user: null
index.browser.js:2 next-firebase-auth [withUser] Calling the logout endpoint.
index.browser.js:2 next-firebase-auth [withUser] Set user to: {id: null, email: null, emailVerified: false, tenantId: null, phoneNumber: null, …}
index.browser.js:2 next-firebase-auth [withUser] Completed the auth API request.
index.browser.js:2 next-firebase-auth [withUser] Set user to: {id: null, email: null, emailVerified: false, tenantId: null, phoneNumber: null, …}
sample_firestore1.tsx:34 Fetch end: Mon Jan 29 2024 10:44:15 GMT+0900 (日本標準時)

It takes about 30 seconds to execute the fetch function (10:43:44 ~ 10:44:15).
Requests and responses to Firestore take very little time; the steps before that take time.
image

Putting { whenUnauthedBeforeInit: AuthAction.RETURN_NULL } in the argument of withUser seems to solve the problem in this repository example. However, it was not a solution for my other application (I could not reproduce it using the example from this repository)

Versions

next-firebase-auth version: "1.0.2"
Firebase JS SDK (firebase): "9.17.1"
Firebase admin SDK (firebase-admin): "^11.9.0"
Next.js: "13.4.9"

To Reproduce
I wrote it in Describe the bug

Expected behavior
I wrote it in Describe the bug

Debug and error logs
Please provide debug logs or errors from onVerifyTokenError and onTokenRefreshError.

Additional context
Add any other context about the problem here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions