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

Incompatible Firebase 9 Modular Mode #262

Open
hffmnn opened this issue Feb 21, 2023 · 4 comments
Open

Incompatible Firebase 9 Modular Mode #262

hffmnn opened this issue Feb 21, 2023 · 4 comments

Comments

@hffmnn
Copy link
Contributor

hffmnn commented Feb 21, 2023

When using this library one is forced to use the firebase 9 compat mode (which will be removed in one of the next versions, see https://firebase.google.com/docs/web/modular-upgrade) because react-admin-firebase seems not to support the modular type. Running this example:

const app = initializeApp(config); // modular way to initialize firebase app
const dataProvider = FirebaseDataProvider(config, { app });

function App() {
  return <Admin dataProvider={dataProvider}></Admin>;
}

logs the following to the console:

Uncaught TypeError: this.app.firestore is not a function

which makes sense, because the firebase 9 way of doing it would be getFirestore(app).

A workaround would be to let react-admin-firebase create the app instance, but:

  • Then there are no bundling benefits (modular mode should have as smaller bundling size, at least that what it was designed for)
  • One might not be able to do so, because there might be multiple app instances.

Did I miss something?

@brownieboy
Copy link

brownieboy commented Mar 10, 2023

I've just started getting this error too. Also updating to Firebase 9.

I'm not even using Firestore. I'm using Firebase Realtime DB for my data store. I was only using react-admin-firebase for the authentication part.

Not to worry. I simply asked ChatGPT to write me a new, standalone authProvider for Firebase 9 and problem solved. I can actually remove react-admin-firebase from build now.

I can post the code if you think it will be of any help to you.

@shidevil
Copy link

@brownieboy Would be great if you can post the code! So now you don't need the react-admin-firebase?

@brownieboy
Copy link

brownieboy commented Mar 12, 2023

As requested, this is my authProvider.js file:

import { getAuth, signInWithEmailAndPassword, signOut } from 'firebase/auth';

const authProvider = {
  login: async ({ username, password }) => {
    try {
      const auth = getAuth();
      await signInWithEmailAndPassword(auth, username, password);
      const user = auth.currentUser;
      const token = await user.getIdToken();
      localStorage.setItem('token', token);
      return Promise.resolve();
    } catch (error) {
      return Promise.reject(new Error(error.message));
    }
  },
  logout: async () => {
    try {
      const auth = getAuth();
      await signOut(auth);
      localStorage.removeItem('token');
      return Promise.resolve();
    } catch (error) {
      return Promise.reject(new Error(error.message));
    }
  },
  checkAuth: async () => {
    const token = localStorage.getItem('token');
    if (token) {
      return Promise.resolve();
    }
    return Promise.reject();
  },
  checkError: async (error) => {
    if (error?.code === 'auth/user-not-found') {
      return Promise.reject(new Error('User not found'));
    }
    return Promise.resolve();
  },
  getPermissions: async () => {
    return Promise.resolve();
  },
  getIdentity: async () => {
    const auth = getAuth();
    const user = auth.currentUser;
    if (!user) {
      return Promise.reject();
    }
    const token = await user.getIdToken();
    return Promise.resolve({
      id: user.uid,
      fullName: user.displayName,
      avatar: user.photoURL,
      token: token,
    });
  },
};

export default authProvider;

No, I don't need react-admin-firebase now because I'm using Firebase Realtime Database, not Firestore.

Note, I had to call get getAuth in my Data Provider in order to keep my session alive. Without this, I kept getting prompted to login over and over:

import { getAuth } from "firebase/auth";

export default (
  firebaseConfig,
  settings = { context: "", imagekey: "images", filekey: "files" }
) => {
  const {
    callbacks: { getListFormatDataCallback },
  } = settings;

  const firebaseApp = initializeApp(firebaseConfig);
  // getAuth() must be called here in order to pick up any previous Firebase
  // authentication from session cookies.
  getAuth();

  const database = getDatabase(firebaseApp);

  const firebaseRTClient = {
    create: async (source, params) => {

@CBrian04
Copy link

Hi guys,

Same error here, I am not able to pass the "app" option to the FirebaseDataProvider function because initializing in firebase v9 way.
For information I have a custom authProvider based on firebase but with some specifics points to handle so not fitting with the given authProvider.
I suppose that it causes a permission error when data in firestore is fetched from dataProvider when a user connect, disconnect and finally reconnect itself. No problem on first connection or when refreshing page. No problem fetching data directly with firestore bypassing the dataprovider.
So I suspect that without furnishing the app in the FirebaseDataProvider config the auth is not synced after logout. I would be happy to not have to switch back to v8 and rewrite lot of code.

Does anybody have found a workaround ?

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

No branches or pull requests

4 participants