Accessing firebase API using redux in React - reactjs

I am creating a react app that should connect to Firebase and query Firestore. I am using react-redux-firebase and redux-firestore to connect to the Firebase API. I however get an error indicating that an Object... is not a function. please assist. Below is my code
I import the two like so
import { reduxFirestore, getFirestore } from 'redux-firestore';
import { reactReduxFirebase, getFirebase } from 'react-redux-firebase';
then I import my Firebase config file like so:
import fbConfig from './config/fbConfig';
My store then follows:
const store = createStore(rootReducer,
compose(
applyMiddleware(thunk.withExtraArgument({ getFirebase, getFirestore })),
reduxFirestore(fbConfig),
reactReduxFirebase(fbConfig)
)
);
The affected line is this
applyMiddleware(thunk.withExtraArgument({ getFirebase, getFirestore })),
It says Type error Object is not a Method.
Please assist. Thanks

This error is usually related to the version of the react-redux-firebase that you are importing. Please, run the below command, to check if this fixes your compatibility issues.
npm i --save react-redux-firebase#next
Besides that, as indicated in this other post here and in the official documentation here, you will need to change your code to fits in the needed setting, for it to work.
Your new code should look more like this.
import { ReactReduxFirebaseProvider } from 'react-redux-firebase'
import { createFirestoreInstance } from 'redux-firestore'
const store = createStore(
rootReducer,
initialState,
compose(
)
)
const rrfProps = {
firebase,
config: rrfConfig,
dispatch: store.dispatch,
createFirestoreInstance // <- needed if using firestore
}
const App = () => (
<Provider store={store}>
<ReactReduxFirebaseProvider {...rrfProps}>
<Todos />
</ReactReduxFirebaseProvider>
</Provider>
);
This code is untested, however, it's based in successful cases and the official documentation, so I believe it should help you. I would recommend you to give it a try using it and checking the URLs I linked here, if you want a better understanding of your issue.
Let me know if the information helped you!

Related

Can we use store from different libraries together in react project?

Right now we are using easy peasy in our project, now we want to remove easy peasy store gradually and replace it with reduxtoolkit. Can we use stores with different libraries in react? Or is any alternative way to deal with this situation.
Tried below which is not working:
**Creating store out of reduxtoolkit**
import { configureStore,combineReducers } from "#reduxjs/toolkit";
import appReducer from "./slice/appReducer";
const rootReducer= combineReducers({
app: appReducer,
});
const store = configureStore({
reducer: rootReducer,
});
**For easy peasy**
import models from './models';
import { createStore } from 'easy-peasy';
const store = createStore(models);
**In main file**
<Provider store={store }>
<Provider store={reduxStore }>
<App/>
</Provider>
</Provider>
**It is failing with Error:**
easy-peasy.esm.js:93 Uncaught TypeError: store.getActions is not a function
Basically Missing step from my side was Importing Provider from correct package.
import { Provider as ReduxProvider } from "react-redux";
import { StoreProvider as Provider } from 'easy-peasy';
<ReduxProvider store={reduxStore }>
<Provider store={easyPeasystore }>
Changing my code with above line helped me in solving problem.

object is not a function when calling `useFirestoreConnect`

I'm using react-redux-firebase and redux-firestore packages.
I'm trying to connect firestore to redux using the useFirestoreConnect hook, but after calling this hook it gives me a TypeError like in this picture.
I've searched in the GitHub issues, docs and here but I'vent fount any solution.
The error: Uncaught (in promise) TypeError: Object(...) is not a function
you see the whole error in this picture:
The console.log error
The TypeError returned
Hello guys I figure out where the problem coming from.
This is for anyone who is looking for a solution.
react-redux-firebase and redux-firestore are having some issues
in versions compatibility, so to skip that I installed the latest
version of the packages!
Clearly there were some differences between old versions and the new
ones of giving your app the redux firebase provider.
The old way might look like this:
const store = createStore(
rootReducer,
composeEnhancers(
reactReduxFirebase(firebase, rrfConfig),
reduxFirestore(firebase),
applyMiddleware(thunk.withExtraArgument({ getFirebase, getFirestore }))
)
);
but if you want to implement hooks in your app and use the useFirestoreConnect this will not work.
In new versions you need to remove the reactReduxFirebase and reduxFirestore from your createStore func and instead use the ReactReduxFirebaseProvider imported from react-redux-firebase and wrap your app inside it, like this:
<ReduxProvider store={store}>
<ReactReduxFirebaseProvider {...rrfProps}>
<BrowserRouter>
<AuthIsLoaded>
<App />
</AuthIsLoaded>
</BrowserRouter>
</ReactReduxFirebaseProvider>
</ReduxProvider>
and passed props: firebase, react-redux-firebase config and any other things you wan. the rrfProps are lik this:
const rrfProps = {
firebase,
config: rrfConfig,
dispatch: store.dispatch,
createFirestoreInstance, //since we are using Firestore
};
and this is the react-redux-firebase config (rrfConfig):
const rrfConfig = {
userProfile: "users",
useFirestoreForProfile: true, // Firestore for Profile instead of Realtime DB
attachAuthIsReady: true, // attaches auth is ready promise to store
};

Redux-firestore with React

So I have been creating an application where a user needs to log into firebase using google authentication. I am using redux, react-redux, react-redux-firebase, redux-firestore, and redux-thunk. I am able to successfully log the user into firebase with the google authentication. I now want to use firestore in order to have a collection of all the users. I have looked at the documentation for redux-firestore and the method of getting/manipulating is a little different. I have tried using the documentation, but I cannot get the functions to work with redux-firestore.
Here is the action
export const signIn = () => (
dispatch,
getState,
{getFirebase, getFirestore}) => {
const firebase = getFirebase();
const firestore = getFirestore();
firebase.auth().signInWithPopup(provider).then(function(result) {
if(result.credential) {
firestore.get({collection: 'users', doc: result.user.uid}).then(function(doc) {
if(!doc.exists){
console.log("new!")
firestore.add(
{collection: 'users', doc: result.user.uid},
{name: firebase.auth.currentUser.displayName});
} else{
console.log("old!")
}
})
}
}).catch((err) => {
})
};
And here is my setup in index.js for the src folder
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import {BrowserRouter} from 'react-router-dom';
import {createStore, applyMiddleware, compose} from 'redux';
import {Provider} from 'react-redux';
import allReducers from './reducers';
import thunk from 'redux-thunk';
import firebase from './Firebase';
import {firebaseConfig} from './Firebase'
import {createFirestoreInstance, getFirestore, reduxFirestore} from 'redux-firestore';
import {ReactReduxFirebaseProvider, getFirebase} from 'react-redux-firebase';
const store = createStore(
allReducers,
compose(
applyMiddleware(thunk.withExtraArgument({getFirebase, getFirestore})),
reduxFirestore(firebaseConfig)
));
const rrfConfig = {
userProfile: 'users',
useFirestoreForProfile: true
};
const rrfProps = {
firebase,
config: rrfConfig,
dispatch: store.dispatch,
}
ReactDOM.render(
<Provider store={store}>
<ReactReduxFirebaseProvider {...rrfProps}>
<BrowserRouter>
<App />
</BrowserRouter>
</ReactReduxFirebaseProvider>
</Provider>,
document.getElementById('root')
);
serviceWorker.unregister();
I know that I have not used createFirestoreInstance in this code, but I was playing around with it.
If anyone could tell me how to get this working, I would appreciate it.
Thanks!
Quick update:
I have figured out how to at least write to firestore using this code
const userRef = firebase.firestore().collection('users').doc(result.user.uid);
userRef.get().then(function(doc) {
if(!doc.exists){
userRef.set({name: result.user.displayName});
}
})
This is not the best (or maybe the right solution), but it does work. It is not using redux-firestore, but is there a better way?
If you're using React, use react-redux-firebase. There's no need for these many complication and the code looks much neater and simpler. Authentication, firestore and all other firebase features works out of the box with just small amount of code. They also comes with React hooks like useFirebase() and useFirestore() instead of you needing to write them on your own.
react-redux-firebase is built on top of redux-firebase and provides all the things you would need in React.
If your app only uses firebase, I would even recommend you use just plain Redux without Redux Thunk or Redux Saga.

"TypeError: Object(...) is not a function" react-redux-firebase

I'm trying to create a project in React and I'm using Firebase. In my react-redux-firebase project one line of code making error but I couldn't fix that. How could I fix this "TypeError: Object(...) is not a function"
I have searched for this problem but couldn't fix the problem.
I'm following a tutorial where the react version is 16.4.1. I'm not sure this is the problem or not
index.js file
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import { createStore, applyMiddleware, compose } from "redux";
import rootReducer from "./store/reducers/rootReducer";
import { Provider } from "react-redux";
import thunk from "redux-thunk";
import { reduxFirestore, getFirestore } from "redux-firestore";
import { reactReduxFirebase, getFirebase } from "react-redux-firebase";
import fbConfig from "./config/fbConfig";
const store = createStore(
rootReducer,
compose(
applyMiddleware(thunk.withExtraArgument({ getFirebase, getFirestore })),
reduxFirestore(fbConfig),
reactReduxFirebase(fbConfig)
)
);
if I comment out the reatReduxFirebase() then it works fine but I need this to work
You could find all codes here: https://github.com/martuza-shimul/React-Blog-app
I'm getting this error every time:
TypeError: Object(...) is not a function
Module../src/index.js
i:/Learning new things/react/pma/src/index.js:17
14 | const store = createStore(
15 | rootReducer,
16 | compose(
> 17 | applyMiddleware(thunk.withExtraArgument({ getFirebase, getFirestore })),
18 | reduxFirestore(fbConfig),
19 | reactReduxFirebase(fbConfig)
20 |
I'm not sure how to fix this. A little bit of help/hint really be appreciated.
Please use this npm packages
npm packages compatibility issue
npm i --save react-redux#5.1.1 react-redux-firebase#2.2.4
This is a react-redux-firebase v2.x.x coding pattern and you probably have v3.x.x installed.
Check which version of react-redux-firebase you are using:
npm ls react-redux-firebase
If the version is 3.0.0 or higher, you need to migrate your code to the new coding pattern. See React-Redux-Firebase v3.x.x Migration Guide for detailed instructions.
The reactReduxFirebase store enhancer is removed in the version v3 and above. You can now create firebase instance using context providers. The same can now be done as:
const store = createStore(
rootReducer,
compose(
applyMiddleware(thunk.withExtraArgument({ getFirebase, getFirestore })),
reduxFirestore(fbConfig)
)
);
const rrfProps = {
firebase,
config: fbConfig,
dispatch: store.dispatch
}
const App = () => (
<Provider store={store}>
<ReactReduxFirebaseProvider {...rrfProps}>
<Todo /> // your Component
</ReactReduxFirebaseProvider>
</Provider>
);
As of now the 'reduxFirestore' is working fine so I want to leave it as it is but I assume the same will happen to it in coming days. So its a good idea to omit compose and reduxFirestore(fbConfig) and instead use:
import { createFirestoreInstance } from 'redux-firestore'
and add createFirestoreInstance to rrfProps as below:
const rrfProps = {
firebase,
config: rrfConfig,
dispatch: store.dispatch,
createFirestoreInstance
}
For more information checkout: http://react-redux-firebase.com/docs/v3-migration-guide.html#remove-createFirebaseConnect-and-createFirestoreConnect
Option 01- adjust npm package versions for react-redux & react-redux-firebase
npm install react-redux#5.1.1 react-redux-firebase#2.2.4
Option 02- Refer v3 ( http://react-redux-firebase.com/docs/v3-migration-guide.html )

react-redux can't find store but it sure looks like it's there

OK - what the heck am I missing... spent a day and a half trying to solve this and am about to ditch redux...
I have the following root route...
...
import configureStore from 'NewApp/client/store';
import createBrowserHistory from 'history/lib/createBrowserHistory';
const history = createBrowserHistory();
const store = configureStore(history);
ReactDOM.render(
<Provider store={store}>
<Router
history={history}
children={routes}
{...clientOptions.props} />
</Provider>
, rootElement
);
...
And I see the store object, but I keep getting an error saying it's not there...
Adding requested additional code:
...
import rootReducer from '../reducers';
const middlewares = [
thunkMiddleware,
loggerMiddleware,
];
const finalCreateStore = compose(
applyMiddleware(...middlewares),
window.devToolsExtension ? window.devToolsExtension() : f => f
)(createStore);
export default function configureStore(history, initialState) {
const store = finalCreateStore(rootReducer, initialState);
syncReduxAndRouter(history, store, state => state.router);
return store;
}
...
...
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { clearNotification } from '../actions/notifications';
import { logout } from '../actions/auth';
import App from '../components/App';
function mapStateToProps(state) {
return {
locale: state.app.locale,
loggingIn: state.auth.loggingIn,
messages: state.app.messages,
notification: state.notification,
title: state.app.title,
user: state.auth.user,
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({
clearNotification,
logout,
}, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(App);
OK, here's the deal... it turns out that the demo app I am using code splits and if you add flux/redux into the mix in additional to all the 'joy' redux has already given, you actually need to 'split' your reducers as well per this repo.
The original error in my question above happened going to any non-root route because webpack code splitting makes those router calls async - basically getting things out of kilter with the reducer(s) in the store. The repo linked to in this answer shows how to keep the router and store in sync with the 'dynamic' reducers.
Am I the only one starting to feel like adding in redux is becoming more work than writing an entire large, complex app in the first place? Seeing those redux 10 line 'counter' app demos made it look so... easy? Anyway, hopefully this unveiling which by the way is not well documented in redux yet can help someone in the future!

Resources