benwinding / react-admin-firebase

A firebase data provider for the react-admin framework
https://benwinding.github.io/react-admin-firebase/
MIT License
457 stars 169 forks source link

Default example produces: Expected first argument to collection() to be a CollectionReference #280

Open dyerrington opened 1 year ago

dyerrington commented 1 year ago

Here's my basic setup:

import {
  Admin,
  Resource,
  ListGuesser,
  EditGuesser,
  ShowGuesser,
  SimpleShowLayout,
  Show,
  Create, SimpleForm,
  List,
  Edit,
  Datagrid,
  TextField,
} from "react-admin";

// import { dataProvider } from "./dataProvider";
// import { authProvider } from "./authProvider";
import { PostList, PostShow, PostCreate, PostEdit } from "./posts";

import UserIcon from '@material-ui/icons/People';
import CommentIcon from '@material-ui/icons/Comment';
import CustomLoginPage from "./LoginPage";

import {
    FirebaseAuthProvider,
    FirebaseDataProvider,
  } from 'react-admin-firebase';

import "firebase/compat/firestore"; 
import "firebase/compat/storage";

import firebase from "firebase/compat/app";

const firebaseConfig = {
    apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
    authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
    projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
    storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
    messagingSenderId: process.env.REACT_APP_FIREBASE_SENDER_ID,
    appId: process.env.REACT_APP_FIREBASE_APP_ID 
}

let firebaseApp;

if (!firebase.apps.length) {
    firebaseApp = firebase.initializeApp(firebaseConfig);
} else {
    firebaseApp = firebase.app(); // if already initialized, use that one
}

// const db = firebase.firestore(); // Add this line
// const storage = firebase.storage();

const dataProvider = FirebaseDataProvider(firebaseConfig, {
    logging: true,
    // watch: ['posts', 'comments'],
    // rootRef: 'rootrefcollection/QQG2McwjR2Bohi9OwQzP',
    // rootRef: 'test/p4BPibI6rQyoYjqlPP0Q',
    // rootRef: 'test/sandbox',
    app: firebaseApp,
    // watch: ['posts'];
    // dontwatch: ['comments'];
    // persistence: 'local',
    persistence: 'session',
    // disableMeta: true
    dontAddIdFieldToDoc: true,
    lazyLoading: {
      enabled: true,
    },
    // firestoreCostsLogger: {
    //   enabled: true,
    // },
});

console.log("Firestore instance: ", dataProvider);
console.log("Firebase App: ", firebaseApp);

const authProvider = FirebaseAuthProvider(firebaseConfig);

export const App = () => (
  <Admin dataProvider={dataProvider} authProvider={authProvider} loginPage={CustomLoginPage}>
    <Resource
    name="posts"
    list={PostList}
    show={PostShow}
    create={PostCreate}
    edit={PostEdit}
    />
  </Admin>
);

I have no problem accessing resources with Firebase library directly:

const db = firebaseApp.firestore();

db.collection("posts").get().then((querySnapshot) => {
    querySnapshot.forEach((doc) => {
        console.log(doc.id, " => ", doc.data());
    });
}).catch((error) => {
    console.log("Error getting documents: ", error);
});

Also seems to let me on just fine with the test user / pass I setup in Firebase so seems at least the API creds are ok. Since this is my first time using this library, I'm sure it's something really dumb that I'm overlooking? Whenver I add the <Resource /> into <Admin />, I get this error:

FirebaseError: [code=invalid-argument]: Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore

image

Thanks in advance for any help!

FrankSandqvist commented 12 months ago

+1

rapuckett commented 11 months ago

Same error. Any ideas on fix? Thanks.

joel-gfdez commented 10 months ago

Same problem here, can't figure out what is wrong.

muddylemon commented 9 months ago

Same error - I've tried multiple versions of the rootRef value, the documentation isn't clear what the value should be. I've also wiped all my rules to a blanket read/write allow and it still fails.

In my app, the data is segregated at the top by "clubs" ie clubs/{clubId}/members and clubs/{clubid}/orders In my firestore rules, a club admin is given general read/write permissions for things below /clubs. For testing purposes i'm hard-coding the clubId to my test club, in practice it will be selected by the admins based on which clubs they are admin for.

my config:

const dataProvider = FirebaseDataProvider(firebaseConfig, {
  logging: true,
  rootRef: "/clubs/test-club",
  app: firebaseApp,
  persistence: "local",
  // disableMeta: true
  dontAddIdFieldToDoc: true,
  lazyLoading: {
    enabled: true,
  },
  firestoreCostsLogger: {
    enabled: true,
  },
});

example resource:

      <Resource name="orders" icon={PointOfSaleIcon} {...OrdersAdmin} />

The permissions aren't a problem on the customer facing app, so I know I can read and write to the appropriate stores.

In my earlier iteration, I had all the "club data" on the top level and it worked fine.

mina-alphonce commented 9 months ago

i have been investigating this for the past 2 days. it look like the function getAbsolutePath in pathHelper.ts returning undefined this is pretty much impossible since the code is quite simple, then I figured out that the bundling has something messed up. i fixed it by going in node_modules/react-admin-firebase/package.json
change the main attribute from

"main": "dist/index.js" to "main": "dist/src/index.js"

it just worked fine with, i tested it with rootRef and without rootRef and seems to work just fine.

this is extremely hacky but seems to work for now at least

TihomirIvanov commented 6 months ago

i have been investigating this for the past 2 days. it look like the function getAbsolutePath in pathHelper.ts returning undefined this is pretty much impossible since the code is quite simple, then I figured out that the bundling has something messed up. i fixed it by going in node_modules/react-admin-firebase/package.json change the main attribute from

"main": "dist/index.js" to "main": "dist/src/index.js"

it just worked fine with, i tested it with rootRef and without rootRef and seems to work just fine.

this is extremely hacky but seems to work for now at least

Why not just import them from dist/src

import {
  FirebaseAuthProvider,
  FirebaseDataProvider,
} from 'react-admin-firebase/dist/src';