react-admin-firebase icon indicating copy to clipboard operation
react-admin-firebase copied to clipboard

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

Open dyerrington opened this issue 1 year ago • 7 comments

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!

dyerrington avatar Jul 10 '23 01:07 dyerrington

+1

FrankSandqvist avatar Jul 19 '23 10:07 FrankSandqvist

Same error. Any ideas on fix? Thanks.

rapuckett avatar Jul 22 '23 18:07 rapuckett

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

joel-gfdez avatar Aug 26 '23 22:08 joel-gfdez

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.

muddylemon avatar Sep 21 '23 17:09 muddylemon

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

mina-alphonce avatar Sep 30 '23 19:09 mina-alphonce

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';

TihomirIvanov avatar Dec 20 '23 14:12 TihomirIvanov