-1

I am trying to figure out how to add authentication to a react app that uses Cloud Firestore rather than Realtime Database.

I followed this tutorial and got the whole thing working. Then - the change I'm trying to add is the move from Realtime Database to Cloud Firestore - this makes a difference to whether authentication works. I have made 20 new projects to try to get this work - totally without the process in the tutorial and just relying on firebase documentation. None of them work.

Currently, I have a config file with:

import app from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
import firestore from "firebase/firestore";

class Firebase {
  constructor() {
    app.initializeApp(config).firestore();
    this.auth = app.default.auth();
    // this.db = app.firebase.database()
    this.db = app.firestore();

  }  

Then, i have a form with this submit handler:

  import Firebase from '../../../firebase.1';

handleCreate = () => {
    const { form } = this.formRef.props;
    form.validateFields((err, values) => {
      if (err) {
        return;
      };
    const payload = {
    // ...values,
    name: values.name,
    email: values.email,
    organisation: values.organisation,
    beta: values.beta,
    role: values.role,
    // createdAt: Firebase.FieldValue.serverTimestamp()
    }
    console.log("formvalues", payload);

    Firebase
    .auth()
    .createUserWithEmailAndPassword(values.email, values.password)
    console.log('Received values of form: ', values);
    Firebase
    .collection("users")
    .add(payload)
    // .then(docRef => {
    //     resetForm(initialValues);
    // })
    .then(e => this.setState({ modalShow: true }))


    form.resetFields();
    this.setState({ visible: false });
    this.props.history.push(DASHBOARD);

  });

    };

At the moment, when I console.log(Firebase) I get:

Uncaught ReferenceError: Firebase is not defined

I have seen this post and followed each one of the recommendations in all of the answers.

I have tried changing the config file uses:

this.auth = app.default.auth();

It makes no difference.

When I try to use this, i get an error that says:

TypeError: _firebase_1__WEBPACK_IMPORTED_MODULE_14__.default.auth is not a function

Does anyone know how to use auth with firebase - where there is a Cloud Firestore instead of a Realtime Database - it's so weird that this makes a difference to whether the authentication tool works.

I've turned off the timestamp entry because I can't get firestore to record that either - but that is a problem for another day. I'm really trying to figure out how to use the authentication tool for now.

NEXT ATTEMPT

I tried to change the firebase.js file so that the config now looks like this:

import app from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';


const devConfig = {

};

const prodConfig = {
};

const config =
  process.env.NODE_ENV === 'production' ? prodConfig : devConfig;


const Firebase = app.initializeApp(config);
const database = app.firestore();
const auth = app.auth();
const settings = { timestampsInSnapshots: true };


export { Firebase, database as default, settings, auth };

Now, I get an error that says:

TypeError: _components_firebase__WEBPACK_IMPORTED_MODULE_2__.default is not a constructor

I have been googling - what is a constructor. What is a webpack imported module number reference etc for the last few hours. I would love to know how to translate these error messages into something understandable.

Googling this exact error message suggests that something is wrong with the way the import and export statements are made. The new export in firebase.js is unusual (but others on Stack Overflow have tried it with problems using Firebase). It's still a question mark for me because I don't understand what the error message means.

The error message points to this line of my src/index.js

ReactDOM.render(

  <FirebaseContext.Provider value={new Firebase()}>

That line comes from:

import FirebaseContext, { withFirebase } from './Context';
import Firebase from '../../firebase.1';
export default Firebase;
export { FirebaseContext, withFirebase };

That file imports from:

import React from 'react';
const FirebaseContext = React.createContext(null);

export const withFirebase = Component => props => (
  <FirebaseContext.Consumer>
    {firebase => <Component {...props} firebase={firebase} />}
  </FirebaseContext.Consumer>
);
export default FirebaseContext;

It would be a huge reveal if anyone has any advice for learning how to learn what error messages mean. For the moment I'm guessing.

Mel
  • 2,481
  • 26
  • 113
  • 273
  • I think the error is because you are calling `new Firebase()` where you just need to call `Firebase` which is the reference to the firebase initialised object. Also probably is better to make it lower case like `firebase` – Hristo Enev Dec 05 '19 at 17:21
  • Thanks Hristo - I'll try that next. The tutorial has it the way I do - it's strange that it would give detailed, but incorrect instructions. Ill try it and let you know. – Mel Dec 05 '19 at 19:56
  • The uppercase Firebase is because the config exports it with that case style. When I remove new, and just have Firebase, the error generated says: TypeError: Object(...) is not a function – Mel Dec 05 '19 at 21:24
  • I am talking about your NEXT ATTEMPT section, which is not exactly by the tutorial. You are not exporting class there. You are just exporting `const Firebase = app.initializeApp(config);`. It will be much easier if you provide your full project. That will be the easiest way someone to help you. – Hristo Enev Dec 06 '19 at 09:00

1 Answers1

0

I just finished the tutorial recently also, but I simplified my firebase file. I export only the reference to the initialised firebase

import app from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';

const config = {
  //...
};

const firebase = app.initializeApp(config);

export default firebase;

And in my project I have:

//...
import firebase from '../../firebase';
//...

useEffect(() => {
  const listener = firebase
    .firestore()
    .collection(COLLECTIONS.USERS)
    .onSnapshot(querySnapshot => {
      setUsers(querySnapshot);
      querySnapshot.forEach(doc => console.log(doc.id, doc.data()));
    });

  return listener;
}, []);
//...

Check out my Github project here -> https://github.com/henev/react-auth-with-firebase

Hristo Enev
  • 2,421
  • 18
  • 29
  • Thanks @Hristo - my only export was Firebase, I've been trying to go back to exporting each different module defined in a separate const. I'll try your approach next. – Mel Dec 04 '19 at 19:09
  • I edited with my Github project. Check it out :) I will add a live version soon probably. – Hristo Enev Dec 04 '19 at 19:12
  • Thanks a lot! I'l check it out today! – Mel Dec 04 '19 at 19:21
  • did you follow the tutorial and then redesign all your components? I can't get these two steps working with the base - it throws an error pointing to the context provider in index.js (TypeError: _components_firebase__WEBPACK_IMPORTED_MODULE_2__.default is not a constructor), but I can see you've moved yours to App.js. I'm working through your code now, but would be good to know if you got the tutorial approach to work before you started with your approach. Thanks again for sharing. I'm trying to follow what you've done. – Mel Dec 04 '19 at 21:35
  • Yes I was following somehow the tutorial but at some point I started redesigning it. As you can see I removed the `Firebase` class and the HOC and context that was going along with it. Basically the only place I am getting firebase is from `firebase.js` where I have only my firebase instance. – Hristo Enev Dec 04 '19 at 21:54
  • I got some ideas from [this video](https://www.youtube.com/watch?v=unr4s3jd9qA) as well. Check it out. – Hristo Enev Dec 04 '19 at 21:57
  • Thanks Hristo - I'm watching it now. Did you actually get the tutorial to work? You've taken a different approach to your structure. I can't get it to work without unpacking it - keen to know if you actually got the tutorial to work? I'm building a new app from scratch now to test what's in the video - but want to understand what's going wrong with the tutorial - it doesn't make sense that switching from realtime database to cloud firestore would stop the authentication from working. – Mel Dec 04 '19 at 22:00
  • It was working but I am not sure at what point I started restructuring. Please send some stackblitz or something if you need further assistance. I can't guess what could be wrong in your code :) – Hristo Enev Dec 04 '19 at 23:36
  • I don't follow what this bit of your code is: {authUser => ( )} – Mel Dec 04 '19 at 23:53
  • I'm trying to figure out how to use your approach. Im very slow to learn. I'll need a couple of days to research what the terms mean in this formation. I'll get back to you. Thanks for sharing your work. – Mel Dec 04 '19 at 23:54
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/203680/discussion-between-hristo-enev-and-mel). – Hristo Enev Dec 05 '19 at 16:06