0

Getting around firebase authentication but it keeps on throwing the following TypeError message and breaks the app:

TypeError: getfirebase is not a function

Please take a look at my store and authReducer if I'm doing it wrong. In my store, I have provided reduxfirestore with getfirestore and also getfirebase to react-redux-firebase. I'm using v2 of react-redux-firebase.

** store.js

import rrfConfig from "../config/rrfConfig";
import { reduxFirestore, getFirestore } from "redux-firestore";
import { reactReduxFirebase, getFirebase } from "react-redux-firebase";
import { createStore, compose, applyMiddleware } from "redux";
import rootReducer from "./reducers/rootReducer";
import firebase from "firebase/app";
import "firebase/firestore";
import "firebase/auth";
import firebaseConfig from "../config/fbConfig";
import thunk from "redux-thunk";
firebase.initializeApp(firebaseConfig);
firebase.firestore();

const initialState = {};

const store = createStore(
  rootReducer,
  initialState,
  compose(
    applyMiddleware(thunk.withExtraArgument({ getFirebase, getFirestore })),
    reactReduxFirebase(firebase, rrfConfig),
    reduxFirestore(firebase)
  )
);

export default store;

**authActions.js

export const signInAction = credentials => {
  return (dispatch, getState, { getfirebase }) => {
    const firebase = getfirebase();
    firebase
      .auth()
      .signInWithEmailAndPassword(credentials.email, credentials.password)
      .then(() => {
        dispatch({ type: "LOGIN_SUCCESS" });
      })
      .catch(err => {
        dispatch({ type: "LOGIN_ERROR", err });
      });
  };
};

**authReducer

const initialState = {
  authError: null
};

const authReducer = (state = initialState, action) => {
  switch (action.type) {
    case "LOGIN_ERROR":
      console.log("login error");
      return {
        ...state,
        authError: "login failed"
      };
    case "LOGIN_SUCCESS":
      console.log("login success");
      return {
        ...state,
        authError: null
      };
    default:
      return state;
  }
};

export default authReducer;

**rootReducer

import { combineReducers } from "redux";
import authReducer from "./authReducer";
import projectReducer from "./projectReducer";
import { firestoreReducer } from "redux-firestore";
import { firebaseReducer } from "react-redux-firebase";

const rootReducer = combineReducers({
  auth: authReducer,
  project: projectReducer,
  firestore: firestoreReducer,
  firebase: firebaseReducer
});

export default rootReducer;

package.json

{
  "name": "ghandhi-land",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "firebase": "^6.0.4",
    "materialize-css": "^1.0.0-rc.2",
    "node-sass": "^4.11.0",
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-redux": "^5.1.1",
    "react-redux-firebase": "^2.2.4",
    "react-router-dom": "^5.0.0",
    "react-scripts": "3.0.1",
    "redux": "^4.0.1",
    "redux-firestore": "^0.8.0",
    "redux-thunk": "^2.3.0"
  }
}

**SignIn component

import { connect } from "react-redux";
import { signInAction } from "../../store/actions/authActions";
class SignIn extends Component {
  state = {
    email: "",
    password: " "
  };

  handleChange = e => {
    this.setState({
      [e.target.id]: e.target.value
    });
  };
  handleSubmit = e => {
    e.preventDefault();
    this.props.signIn(this.state);
  };

  render() {
    return (
      <div className="container">
        <form onSubmit={this.handleSubmit} className="white">
          <h5 className="grey-text text-darken-3">Sign In</h5>
          <div className="input-field">
            <label htmlFor="email">Email</label>
            <input type="email" id="email" onChange={this.handleChange} />
          </div>
          <div className="input-field">
            <label htmlFor="password">password</label>
            <input type="password" id="password" onChange={this.handleChange} />
          </div>
          <div className="input-field">
            <button className="btn pink lighten-1 z-depth-0">Login</button>
          </div>
        </form>
      </div>
    );
  }
}
const mapDispatchToProps = dispatch => {
  return {
    signIn: credentials => dispatch(signInAction(credentials))
  };
};

export default connect(
  null,
  mapDispatchToProps
)(SignIn);
4
  • Your code seems fine. Could you console.log the value of getFirebase in store.js? Also, where are you exactly getting the TypeError error? Is it when you are executing the signInAction method? Commented Jun 2, 2019 at 11:18
  • when i console.log getfirebase, this what it saying ƒ getFirebase() { if (!firebaseInstance) { throw new Error('Firebase instance does not yet exist. Check your compose function.'); } return firebaseInstance; } Commented Jun 2, 2019 at 11:34
  • and yes it throws this typeError when executing the signInAction Commented Jun 2, 2019 at 11:37
  • @mgarcia. why is the getfirebase undefined? Commented Jun 2, 2019 at 11:55

1 Answer 1

1

When you are composing the redux middlewares you are applying the thunk middleware with this statement:

applyMiddleware(thunk.withExtraArgument({ getFirebase, getFirestore }))

The names of the methods you are passing as an extra argument are in camelcase notation: getFirebase and getFirestore.

However, when you are trying to retrieve the extra argument in authActions.js you are destructuring it as getfirebase:

return (dispatch, getState, { getfirebase })

You should destructure your object with the same notation (in camelcase). So, your code should be:

return (dispatch, getState, { getFirebase })
Sign up to request clarification or add additional context in comments.

1 Comment

it worked. thank you very much. i have being on this for 2 days now

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.