prescottprue / react-redux-firebase

Redux bindings for Firebase. Includes React Hooks and Higher Order Components.
https://react-redux-firebase.com
MIT License
2.55k stars 559 forks source link

createUser profile is using database instead of firestore, even when useFirestoreForProfile is true #976

Closed bawahakim closed 3 years ago

bawahakim commented 4 years ago

Do you want to request a feature or report a bug?

Bug

What is the current behavior?

When creating a user with createUser and passing in a profile, I get the following error : Error: You attempted to use 'firebase.database' but this module could not be found. I have useFirestoreForProfile: true in my config. User is created correctly, but profile is not. All other firebase/firestore functions work correctly. I can also get an existent profile using useSelector((state) => state.firebase.profile);

I feel it might be something very simple that I am missing. Would appreciate any help.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via codesandbox or similar.

Store is setup as so. I am using Rematch, but it should be the same:

import { init } from "@rematch/core";
import firebase from "@react-native-firebase/app";
import { firebaseReducer } from "react-redux-firebase";
import { firestoreReducer, createFirestoreInstance } from "redux-firestore";

import * as models from "./models";

const config = {
  userProfile: "users",
  useFirestoreForProfile: true,
  enableLogging: false,
};

const store = init({
  models,
  redux: {
    reducers: {
      firebase: firebaseReducer,
      firestore: firestoreReducer,
    },
  },
});

export const rrfProps = {
  firebase,
  config,
  dispatch: store.dispatch,
  createFirestoreInstance,
};

export default store;

My App:

import React from "react";
import { Provider } from "react-redux";
import { ReactReduxFirebaseProvider } from "react-redux-firebase";

import store, { rrfProps } from "./store";
import RootNavigator from "./app/nav/RootNavigator";

const App = () => {

  return (
    <Provider store={store}>
      <ReactReduxFirebaseProvider {...rrfProps}>
          <RootNavigator />
      </ReactReduxFirebaseProvider>
    </Provider>
  );
};

export default App;

Then calling onSubmit={({ email, password }) => { firebase .createUser({ email, password }, { username: "test", email }) .then((data) => console.log(data)); }} in a register form.

What is the expected behavior?

It should create a new user doc in the users collection in firestore.

Which versions of dependencies, and which browser and OS are affected by this issue? Did this work in previous versions or setups?

I have not tried previous versions, tested on react-native on android.

    "@rematch/core": "^1.4.0",
    "@react-native-firebase/app": "^7.3.0",
    "react": "~16.9.0",
    "react-native": "0.61.5",
    "react-redux": "^7.2.0",
    "react-redux-firebase": "^3.6.0",
    "redux-firestore": "^0.13.0",
bawahakim commented 4 years ago

I dug a bit in the source, and I think I found the culprit: in actions/auth.js, in createUserProfile, when it does the check in

  if (!config.userProfile || (!firebase.database && !firebase.firestore)) {
    return Promise.resolve(userData)
  }

I think the check for firebase.database actually calls the database package. It it's not installed, that's how you get the Error: You attempted to use 'firebase.database' but this module could not be found. I tried adding a null check !firebase?.database but it doesn't fix the problem. I have removed the line in my own package, but that would probably break it if for other people if I do a PR.

@prescottprue , any suggestion for a full fix?

Thanks

prescottprue commented 4 years ago

Maybe we can switch it to check if typeof firebase.database === 'undefined'? Not sure if that will still throw the error

When trying in codesandbox to do firebase.database, I just get undefined and no error, so wondering how/where the error is thrown. I also couldn't find that wording anywhere in the firebase sdk when looking to see how they check for it

bawahakim commented 4 years ago

Hm I did a bit more research and I think it turns out "@react-native-firebase/app": "^7.3.0" is the culprit. That firebase object seems to have a database property, that whenever is referenced tries to call the @react-native-firebase/databasemodule. Since it's not installed, I get the error thrown. I tried to simply do a console.log(typeof firebase.database) and I still get the error thrown.

What is weirder, if I do a Object.keys(firebase), I don't see the key anywhere. However, if I do firebase.hasOwnProperty('database'), I get true back.

I assume this is now an issue with @react-native-firebase? Or is there a way we can fix this in react-redux-firebase?

prescottprue commented 4 years ago

Yeah, it sounds like it may be a deviation between the functionality of the firebase JS SDK and react-native-firebase

There may be a change that can be made in react-redux-firebase to handle this, but yeah we should find out from them hot to test whether or not a service exists

TMcLoone commented 4 years ago

Did you guys get anywhere with this? Just hitting the error myself

bawahakim commented 4 years ago

Well, if we try to fix the problem in react-redux-firebase, it might break the library for some people. We'd have to investigate with the React Native Firebase library.

For now, I forked the project and removed the check for firebase.database, so it should work for you. You can use this in your package.json. I hope it's not against the rule to post a fork like that :)

"react-redux-firebase": "git+https://github.com/feelthepain444/react-redux-firebase"

prescottprue commented 4 years ago

@feelthepain444 Not at all against the rules, thanks for setting it up and sharing! We are all just trying to help each other get things working at the end of the day 😄

It would be awesome to work this into react-redux-firebase somehow, maybe behind an config option to begin with until we can figure out a better way to detect. Open to a PR if anyone gets a chance

arunkmoury commented 3 years ago

@bawahakim I tried to use your solution but it is not working

I am getting error "You attempt tp use 'firebase.firestore' but this module could not be found.

arunkmoury commented 3 years ago

I found solution may be it work for you too.

import firestore in the store where you add firebase config

import { createStore, applyMiddleware, compose } from 'redux'; import ReduxThunk from 'redux-thunk'; import { reduxFirestore, getFirestore } from 'redux-firestore'; import { reactReduxFirebase, getFirebase } from 'react-redux-firebase'; import rootReducer from './reducers'; import firebase from '@react-native-firebase/app'; import '@react-native-firebase/firestore'; import '@react-native-firebase/auth';

const middlewares = [ReduxThunk.withExtraArgument({ getFirebase, getFirestore })];

const rfConfig = { userProfile: 'users', useFirestoreForProfile: true // Firestore for Profile instead of Realtime DB }

export default Store = createStore(rootReducer, {}, compose( applyMiddleware(...middlewares), reduxFirestore(firebase, rfConfig), ))

if you got database library issue you can import it too

prescottprue commented 3 years ago

@arunkmoury Correct - you need to have Firestore imported in order for it to be used. Also worth noting the reactReduxFirebase` store enhancer is no longer part of the current react-redux-firebase API - you don't seem to be using it, but it is imported in you example.