⚠️ This lesson is retired and might contain outdated information.

Building a React.js App: Using ReactFire to Add Data Persistence

Tyler McGinnis
InstructorTyler McGinnis
Share this video with your friends

Social Share Links

Send Tweet
Published 9 years ago
Updated 6 years ago

In this video, we’ll tie in ReactFire from Firebase in order to implement persistence into our application for our Notes component as well as walk through how to properly display a list of data.

Click here for JSON data to seed your database.

Now what we're going to do in this video is we're going to hook up our firebases so we can start persisting these notes, and we're going to build out the rest of this notes component so that we get a nice little unordered list of all of our notes that are in firebase. So let's go ahead and jump to our code, and what we're going to do first is we are going to use this thing called ReactFire that Firebase made that makes it so that our component state can be bound to a Firebase endpoint.

Meaning whenever a Firebase endpoint changes, our state will automatically update with the data that's there. So head to your terminal and go ahead and install it's called ReactFire. Then once that finishes, as a side note really quick you might be wondering why we're getting this error, that's because we've installed webpack globally so that we can use the command line tools, but we haven't installed it locally. It's not really necessary, but I'm going to install it locally just so this error goes away.

So what we'll do is go ahead and run npm install dev webpack. That will make it so whenever we install new packages this error isn't getting thrown. Go ahead and head over to your profiles.js file and then require ReactFireMixin. You can do it just by requiring ReactFire so what we're going to do, as the name suggests, is we are going to add ReactFire as a mixin into your component.

What we're going to do is go ahead and give your class a mixins property, and then the value is going to be an array with ReactFireMixin as the first item in that array. What this is doing is it's going to take your instance, it's going to mixin some certain functionalities so that we can use that new functionality. So this is literally taking the this keyword of your class and it's adding a few ReactFire mixin methods onto that, so that we can use those later.

Now what we want to do is we're going to introduce a brand new lifecycle event called componentDidMount. Here is where you're going to want to all your Ajax requests, it's where you're going to want to set up all your Firebase listeners, the componentDidMount lifecycle event will be called right after your component mounts to the view. So it's pretty straightforward, but basically when the component mounts this callback will be called.

What we're going to do here is the very thing we want to do is we're going to create a new reference to our Firebase. If you've never used Firebase before, what we're doing here is we're going to create a new instance of Firebase and we're going to pass it the URL of where our project is located. So if I head over to my Firebase dashboard, you'll notice all I did was create a new project and you'll notice there's this URL.

This URL is kind of the base of our project, so if I head back over to my code all I'm doing here is I'm saying, "Hey, create me a new instance of Firebase which is going to return me an object full of all these Firebase-y type properties. I'm going to save that on my instance under the ref property. Then once I do that, I'm going to then call bindAsArray, and the reason that's this keyword now has a bindAsArray property, is because that's exactly what our ReactFire mixin did.

It took our context, it took our this keyword and added a few properties to it and one of those is bindAsArray. BindAsArray takes two arguments the first argument is a reference to your Firebase, and the second argument is the property on your state that you want to bind the Firebase data to. So looking back at Firebase you'll notice that we have our endpoint and basically at our root location we have all these user names. If I come and click on one of these user names, notice the URL changed.

This gives us a little bit of insight into how we want to bind to the specific property in our state, because if we're here and we're at Tyler's profile, we want to bind to \tyler, or if we come here and the user name is jclingwall, then we want to get all of jclingwall's information. So what we're going to do is let's go ahead and make a child ref which is this.ref.child and then we're going to pass it the username property.

So .child is a Firebase thing, and it says hey dial 1 if this is our root, and it is because that's a reference we created with just the this specific URL. If we want it to then go into jclingwall, notice how it goes \jclingwall. That's exactly what we're doing here, is we're basically just saying take our ref and then go one deeper into whatever this is, jclingwall, tylermcginnis, whatever it is.

Now what we're going to do is we're going to pass bindAsArray our child ref which is again, a reference to this specific username's endpoint in Firebase, and then we're going to pass it the property on the state that we want to bind to which is notes. So now, when this component mounts it's going to set up this binding between our local state and Firebase, and this.state.notes should be the data that's located at this specific Firebase endpoint.

What's nice as well, is whenever this Firebase endpoint changes, that's going to update our local state as well. But what we don't want to do is add all these Firebase listeners and never get rid of those. So what we're going to do is introduce a brand new lifecycle event called the componentWillUnmount.

Whenever this component unmounts, what we're going to do is we're going to call the unbind property on ReactFire and we're going to pass it notes so that it will remove that listener so it's not always listening and not always trying to update our state even after our component has moved on. Before we forget let's go ahead and require Firebase, and also npm install Firebase so that we can do line 18 here. So I'm going to go ahead save our Firebase = require Firebase.

Whoa. Now then I'm going to head over here to my terminal and I'm going to npm install Firebase. Now that we have Firebase, let's go ahead and make some changes to our UI. So the very first thing I'm going to do, and this is just preparatory for future lessons, is notice here we're passing in the username to userprofile, let's go ahead and do that for our repos component. So our repos component has access to the username, let's also do that for our notes component.

I'm also going to delete this.props on here, so that's not clouding anything that we see. Then let's go ahead and go over to our notes component and instead of just puking the notes to the screen, React is actually going to throw an error in React .14 because you can't just puke a whole array to the screen, it needs to be a string or something like that. So what we're going to do is let's go ahead and remove this line, and now let's go ahead and just console.log notes and then this.props.notes.

So now what we should see is if we go and refresh this, let's go ahead and start webpack, all right everything's good. If we refresh this what we should see is it's logging our notes to the console. You'll notice here that it logs 1,2,3 because what we've done is in our profile view we've set the initial notes values to an array of 1, 2, and 3.

Then what happens is Firebase comes and sets our listeners, and then eventually we get a bunch of our notes like this, which has a key value which is the key in our key property, which is the key of the specific item in Firebase, and then a value property which is the item at that value.

So what's cool about Firebase, this is all real time. So if I come in here and I say change this from "Hi" to "Hello" what we should see is over here, we now have brand new notes, and we see "Hello." So head back over to your code and let's finish formatting the notes component.

First, notice we're passing notes to our notes component, and we are here and so let's go ahead and change this around a little bit. Very first thing is instead of just saying notes, I'm going to have an H3 tag, and we're going to say notes for this.props.username. Then below that, let's go ahead and instead of making it so this component is worried about styling everything, let's go ahead and make a brand new component. So here's our fixed example.

We could have everything just be in one component, but that's kind of not the point of React, we want multiple components and we want to be able to have reusable components. So let's make a component which takes in an array of items and will loops over those array and create an unordered list for us. If we head back over to our code, let's go ahead and inside of our notes folder, let's create a new file called noteslist.js.

Here we're going to require React and we're going to create a component called noteslist and let's go ahead and module.export that. All right, so the UI for this component is going to be pretty simple. We are going to return an unordered list has a class name of listgroup which is just a bootstrap thing. Here what we want to do is we want to have a bunch of LI tags that we want one LI tag for each item in the array that we're going to pass this component.

So what we're going to do is we are going to map over the notes that we're getting from the parent component. So if you've never used map before, basically all it does is it allows you to iterate through every item in an array and modify each item in an array separately, and then spit out a new array with each item modified. So say for example we had an array of 1, 2, and 3.

What we can do is we could call .map on that array, and pass it a callback function, and then what we can do is if we return item+1, the very first iteration or the very first time this callback is ran, item is going to be 1, or the first item in our array, and index is going to be 0, so if we return item+1, eventually we're going to have a brand new array that looks like 2,3, and 4 getting returned from this.map function.

So imagine if these were all now notes, and if we were mapping over these notes what that is going to return us is a brand new array after we've modified each note. So what we're doing is if these were .props.notes, what we can do is we can wrap each note in a list item so that we then get an array of list items with some note inside of it.

So what we're going to do is for each item in the array we're going to return a new list item with a class name of listgroupitem, it's going to have a key of the index, and index is just 0,1,2,3, just normal indices for arrays, and then inside of this list item, we are going to show the note at .value, and you might be asking why is .value? If you remember, what Firebase does is it wraps each item in an object that has a key property and a .value property.

We only care currently about this .value property. Now let's go ahead and close our LI tag, and now we have notes which is an array of list items, and we will just throw that here, so inside of our unordered list, we have an array of list items. So the last thing we need to do is head back over to our notes component and let's go ahead and require noteslist, and then we want to...let's delete all this stuff.

Instead, we want to use noteslist and we are going to pass it notes which is coming down from our parent component. So notice that you can pass down properties as far as you want. So our notes originally started at our profile, then go to our notes component, and then we're passing them down to our noteslist component. Let's go ahead and close this noteslist component, check that webpack is still working, it is, and in our app we should see if we hit refresh all of our items that are in Firebase.

Chris Anderson
Chris Anderson
~ 9 years ago

Would you mind including an export of your firebase instance?

Kent C. Dodds
Kent C. Dodds
~ 9 years ago

If I'm not mistaken, ReactFire will unbind the refs that you bind automatgically (here).

However, because you create an additional reference to a Firebase that is not explicitly bound, do you not have to clean up that one? I'm talking about the this.ref = new Firebase('...'); I'm asking honestly. I don't know whether you have to clean that up yourself or not.

Paul
Paul
~ 9 years ago

+1 I really need the data to go any further

Michael
Michael
~ 9 years ago

+1 on the data. Would it be possible to add this to the Github repo @Tyler?

Benjamin Gandhi-Shepard
Benjamin Gandhi-Shepard
~ 9 years ago

I just created my own data at Firebase. I only made one user. Also, I've never used Firebase before. It took me about 30 min (including the Firebase tutorial) to figure it out.

Joel Hooks
Joel Hooks
~ 9 years ago

Here's some JSON to seed your database.

Marcelo
Marcelo
~ 9 years ago

I see some people I little frustrated because of the Firebase part: just create an account in case you don't have one. In Firebase go to Data in the upper right corner. Go to this link http://cloud.egghead.io/code/0s1a2x2X3P2c and copy that JSON or download the file, you once do it, create a JSON file with that info, then hit Import Data, and select the JSON file you just create. That's it.

miguel
miguel
~ 9 years ago

you have any idea why the data i am getting is returning both the property and value, instead of just the value like in the video

miguel
miguel
~ 9 years ago

componentDidMount: function(){ this.ref = new Firebase('https://githubnote-taker.firebaseio.com'); var childRef = this.ref.child(this.getParams().username); this.bindAsArray(childRef, 'notes'); } This is what i have, but when i run this, my notes shows both the property and the value like this Notes: What a guy-JugSizVlM-1ijz6OPxZNew note-JugSlbdwr9jTIZZjurt What am i doing wrong? how do i get just the value like in the video?

miguel
miguel
~ 9 years ago

There was an update to ReactFire on the 15th and i think that had something to deal with it, still not sure how to fix it

Joel Hooks
Joel Hooks
~ 9 years ago

Talked to Tyler and he said the new 0.5.0 release of ReactFire is causing issues and that for the sake of the lesson you will want to explicityl npm install reactfire@0.4.0 --save to use v0.4.0 for now. We will update the video as soon as possible, but the "old" version works fine.

Designit
Designit
~ 9 years ago

Hi,

I get this weird problem whenever I require ReactFireMixin:

Uncaught TypeError: Cannot set property 'ReactFireMixin' of undefined

Tyler McGinnis
Tyler McGinnisinstructor
~ 9 years ago

Did you npm install reactfire?

Designit
Designit
~ 9 years ago

npm install reactfire@0.4.0 --save

console inspect shows me reactfire package file line 16 as an error. So its there and all, however itself triggers an error.

this is how i require: var ReactFireMixin = require('reactfire'); and it instantly gives an error.

Tyler McGinnis
Tyler McGinnisinstructor
~ 9 years ago

Hmmm. Mind throwing it up on Github and I'll take a look?

Designit
Designit
~ 9 years ago

Hi, Instead of Github, here is an archive. https://drive.google.com/open?id=0BxyeG-X_QaYVUkp1bWtSTk43Q28

Tyler McGinnis
Tyler McGinnisinstructor
~ 9 years ago

I just requested access to the doc.

Aarron
Aarron
~ 9 years ago

Getting the same error as Jesper... Uncaught TypeError: Cannot set property 'ReactFireMixin' of undefined

Any ideas on this issue?

Tyler McGinnis
Tyler McGinnisinstructor
~ 9 years ago

You're correct on the ReactFire automagical unbounding comment. (but explicit is better, right? :) ).

About this.ref, I've never worried (or seen anyone worry) about cleaning up any new instances of Firebase. I could be mistaken (really hope I'm not) but I don't think you have to clean up instances of Firebase like you would, say setting an actual listener.

Nate Peterson
Nate Peterson
~ 9 years ago

Rather than downgrading the version of reactfire, you can also update your code in NotesList.js. In the part where you are using the map function to generate an array of list items, just update the contents of the list item from {note} to: {note['.value']}

Looking at the Firebase docs, I'm still not positive this is the "correct" way to do this, but it works for now.

odfw
odfw
~ 9 years ago

I was still experiencing this even with the 0.4.0 of reactfire, seems there were some updates on firebase as well. Along with the reactfire@0.4.0 I also had to use npm install firebase@2.2.7 --save before the tut stopped showing the value:key in the notes.

Andrew
Andrew
~ 9 years ago

componentDidMount: function(){ this.ref = new Firebase('https://githubnote-taker.firebaseio.com'); var childRef = this.ref.child(this.getParams().username); this.bindAsArray(childRef, 'notes'); } This is what i have, but when i run this, my notes shows both the property and the value like this Notes: What a guy-JugSizVlM-1ijz6OPxZNew note-JugSlbdwr9jTIZZjurt What am i doing wrong? how do i get just the value like in the video?

I was able to get the desired results by modifying line 7 of NotesList.js to reference only the value of the database key:value pair.

{note['.value']} instead of {note}

EDIT: Looks like Nate beat me to it by a bit. That's what I get for not reading page 2.

egghead eggo
egghead eggo
~ 8 years ago

The lesson video has been updated!

Indrek Lasn
Indrek Lasn
~ 8 years ago

Cheers to that!

kennly
kennly
~ 8 years ago

Tyler, I am having the same issue in the updated tutorial. "Cannot set property 'ReactFireMixin' of undefined" is there anyway to solve it?

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

Hi Kennly,

Make sure all your code is matching what's in the Repo (https://github.com/tylermcginnis/github-notetaker-egghead/blob/05-reactfire/app/components/Profile.js) quite a few people have gone through the updated videos (including myself again) and we haven't had any issues. If issues persist, post your code on github and tweet me the link and I'll check it out.

compile
compile
~ 8 years ago

Installed reactfire and got this warning:

npm WARN In reactfire@0.5.1 replacing bundled version of react with react@0.13.3

From Cli,

$ npm list react

├── react@0.14.3 └─┬ reactfire@0.5.1 └── react@0.13.3

Does it mean reactfire uses react@0.13.3 instead of the installed version, 0.14.3?

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

Yeah you're exactly right. I'm actually not sure why React-Fire has React as a dependency. I'm investigating further right now.

Luis
Luis
~ 8 years ago

I keep getting these warnings that look like these: WARNING in ./~/react/lib/ReactBrowserEventEmitter.js There is another module with an equal name when case is ignored. This can lead to unexpected behavior when compiling on a filesystem with other case-semantic. Rename module if multiple modules are expected or use equal casing if one module is expected.

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

Check that the spelling on your imports is correct. If everything looks good, compare what you have with what's in the Repo on github.

~ 8 years ago

Hi Tyler,

For what it is worth, I'm having the same problem as Kennly. I can't see where the code varies. Seems to be a webpack issue in my opinion.

	  if (true) {
	    // AMD
	    !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function () {
	      return root.ReactFireMixin = factory();
	    }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	  } else if ((typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object') {
	    // CommonJS
	    module.exports = factory();
	  } else {
	    // Global variables
	    root.ReactFireMixin = factory();
	  }

The error occurs on the line return root.ReactFireMixin = factory(); where apparently root is undefined. Not sure what to make of it.

Mark Harrell
Mark Harrell
~ 8 years ago

6:14: "Whoa"? XD

Ashwin
Ashwin
~ 8 years ago

How do you get your npm install to look so good with the real-time feedback?

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

Hi Ashwin. Not 100% sure to be honest. Which version of npm are you running? I'm running npm3.

mLuby
mLuby
~ 8 years ago

In case anyone else runs into this, I was getting Uncaught Error: ReactFire: this.state.notes is not bound to a Firebase reference. The this.unbind('notes') was the culprit, so I removed it. Based on previous comments it sounds like the unbinding happens automagically anyway.

Springload
Springload
~ 8 years ago

I'm having trouble with my code - I don't seem to be getting the objects with the key and values. I am using gulp instead of webpack, but was wondering if someone could have a look at my code and see where I am going wrong? https://github.com/claireynz/git-search

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

You're using an old version of React Fire. You're using 0.4.0 when you need to use >0.5.0

Saravanan
Saravanan
~ 8 years ago

Hi Tyler, I just subscribed today to egghead.io. Thanks for the wonderful videos. I am currently working on a migration project to migrate GWT to React Js. The legacy application has a bunch of servlets that interacts with GWT code. What would be a good approach to have React JS code interact with servlets? Can you point me to any resource that you may have in egghead?

Philip Hancock
Philip Hancock
~ 8 years ago

Hi Tyler,

I am having the same problem with the Cannot set property 'ReactFireMixin' of undefined Error and can't see any code errors. I have just started Egghead.io today specifically for this course. Can you see any problems in my Code?

https://github.com/pdhancock/egghead-react-gh-notetaker

I am stuck at Video 5..

Thanks,

Philip

Hi Tyler,

For what it is worth, I'm having the same problem as Kennly. I can't see where the code varies. Seems to be a webpack issue in my opinion.

	  if (true) {
	    // AMD
	    !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function () {
	      return root.ReactFireMixin = factory();
	    }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	  } else if ((typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object') {
	    // CommonJS
	    module.exports = factory();
	  } else {
	    // Global variables
	    root.ReactFireMixin = factory();
	  }

The error occurs on the line return root.ReactFireMixin = factory(); where apparently root is undefined. Not sure what to make of it.

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

Hmm your code does appear to be the same but I opened my version and then moved that bundle over to your project and it worked - so there's gotta be a difference somewhere. I'll keep looking and see if I can find anything.

Rebecca
Rebecca
~ 8 years ago

Hi,

I'm pretty focused on learning React, and I'm struggling to find what I need in Firebase. I wish you'd gone a little more slowly in teaching the basics of Firebase and introduced the concepts in a whole additional video - this was glossed over very quickly.

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

Hi Rebecca,

That's a fair request. Have you checked out the Firebase docs? They've actually put a lot of thought and emphasis on them so they should have everything you're looking for. Let me know if I can help.

Tyler

~ 8 years ago

I'll second Rebecca's request. I was making good progress in the tutorial until the Firebase part.

Do I need to change the firebase url in Profile.js to my specific account somehow? Or should the line work as shown in the tutorial and github file?: this.ref = new Firebase('https://github-note-taker.firebaseio.com/');

I'm working from a Cloud9 ide -- might that introduce some 3rd party authentication requirement when trying to reach firebase?

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

The URL should still work and Cloud9 shouldn't be causing problems. Check your code against the master repo for any differences if you're having issues. https://github.com/tylermcginnis/github-notetaker-egghead. If you're still stuck let me know and I can help.

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

Hi Saravanan, I have 0 experience with GWT so I can't offer many suggestions. Sorry!

~ 8 years ago

Got it working -- though more by accident (hindered by an obvious lack of logical thinking on my part).

a) I had to first (duh) type a user name that exists in your firebase instance (i.e., 'tyler') -- suddenly I had the notes. I had a random user name in the url from playing around in the prior lessons -- so of course no notes were found for this random username.

b) my chrome dev tools is not showing the listening activity (though has behaved generally per the tutorial) -- this threw me off as there's no evidence of the listening -- still not sure why this is, but once I had a good username that pulled notes, this is less of an issue.

c) to do the interactivity proof you show in the tutorial, I had to substitute your firebasio.com url with my own account (and using the json data provided at the request of other users). This seems obvious now, but from the tutorial and your reply above I was working under the impression that I wouldn't need to have an account or change the url to do exactly as the tutorial shows. So much is explained so well (and so specifically) that the lack of a qualifier in this case tripped me up. ("of course you'll need to type a username that's in the database, like 'tyler' or..."; "if you want to test the interactivity you'll need to create your own firebase account, upload the json data and change the url to your account...").

So, small complaints aside, I'm a customer because your tutorials are well paced, very specific, and comprehensive -- even if on occasion I need the obvious stated just a little more obviously.

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

Thanks for the in depth and very rational critique. Feedback is noted.

Shankar Dhanasekaran
Shankar Dhanasekaran
~ 8 years ago

i am getting following error in console. How could i fix it?

Uncaught Error: Invariant Violation: Objects are not valid as a React child (found: object with keys {.value, .key}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of Notes.

i am using the same code at https://github.com/tylermcginnis/github-notetaker-egghead/blob/05-reactfire/app/components/Profile.js

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

In Notes change <p> {this.props.notes}</p> to <p> {JSON.stringify(this.props.notes, null, 2)}</p>

Sebastian
Sebastian
~ 8 years ago

Any chance you can update this to work with rebase and ES6?

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago
Ian Moreno
Ian Moreno
~ 8 years ago

Ahhh thank you! I was making the same mistake (a) in the above comment, using a random name not included in the seed data

Pål Taule Brentebråten
Pål Taule Brentebråten
~ 8 years ago

Uncaught TypeError: Cannot set property 'ReactFireMixin' of undefined

Did anyone figure this out? I have the same problem. I have the excact same code, Uninstalled/reinstalled all the packages to the versions used in the tutorial, remade the bundle file... but still get the same error :(

Matthew
Matthew
~ 8 years ago

Thank you, I muddled through all the same issues as well, and having to type a username that existed in the database was tripping me up.

Desarrollo Produccion
Desarrollo Produccion
~ 8 years ago

here's solution https://github.com/blackendstudios/react-students/commit/2757df9c76fc1f5e37557abe46b8b9e6d2507b06#diff-7165d48e1b473307742a0db5952bbba2L27

Bharat Soni
Bharat Soni
~ 8 years ago

Nothing happens when I change the url from /Github to /Grobiou. Both are present in the JSON file. I was expecting change in notes... May be you will cover that in next video?!

Felice
Felice
~ 8 years ago

Great Solution !

Robert
Robert
~ 8 years ago

I used your URL given in the video just to see if things worked... the short answer is things did, but there's hundreds of rows in the database now under the /tyler profile. Which locks up my browser, to the point that I thought I broke something. :-D

Importing the data into my own Firebase instance fixed this but maybe the "original" needs some cleanup.

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

Done.

Wojciech Urbański
Wojciech Urbański
~ 8 years ago

The link doesn't work anymore :(

Justine Akehurst
Justine Akehurst
~ 8 years ago

It's now May 2016, and Firebase still has no plan on supporting ES6, or developing a higher-order React component so that we don't have to do Mixins. I'm learning React from the beginning right now. I have a feeling this tutorial series needs to be redone with ES6 from the beginning, and using another persistence technology that works with ES6 and modern React, and the ability to persist without an active internet connection for those of us that want to run through this tutorial offline.

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

Hi Justine,

You're making two very large assumptions here. First is that Firebase doesn't work with React without using React Fire and second is that using Classes are the standard way to create components in React.

I actually don't use React Fire because I don't feel like it's needed and it definitely doesn't work if you add a data model like Redux.

Also I, along with many Facebook developers, still use createClass over Classes in React.

Tyler

kevin
kevin
~ 8 years ago

Tyler, why do you and "many Facebook developers", use createClass over classes in react?

Russell Wells
Russell Wells
~ 8 years ago

Hello all, if you're doing this post May 2016, in your Firebase you will need to change the Rules like so to get the data to display:

{ "rules": { ".read": "auth == null", ".write": "auth != null" } }

Mac
Mac
~ 8 years ago

For those looking to use the new Reactfire API, this got me going. https://firebase.google.com/docs/web/setup#add_firebase_to_your_app
You also need to include your config var, where is the best place for that to go?

var config = {
  apiKey: '',
  authDomain: '',
  databaseURL: '',
  storageBucket: '',
};
Firebase.initializeApp(config);
componentWillMount: function(){
    this.ref = Firebase.database().ref('usernames');
    var childRef = this.ref.child(this.props.params.username);
    this.bindAsArray(childRef,'notes');
  },
Ross
Ross
~ 8 years ago

Thanks, Russell. I can now read data from Firebase!

Daniel
Daniel
~ 8 years ago

For now I'm using like this:

// Profile.js
...
var Notes = require('./Notes/Notes');
var ReactFireMixin = require('reactfire');
var Firebase = require('firebase');

var config = {
  apiKey: "AIzaSyA9IdUO3ZMpI3-pKEuzDceKccTiGeGOp4Y",
  authDomain: "kuroski-note-taker.firebaseapp.com",
  databaseURL: "https://kuroski-note-taker.firebaseio.com",
  storageBucket: "kuroski-note-taker.appspot.com"
};
Firebase.initializeApp(config);
...
componentWillMount: function() {
  this.ref = Firebase.database().ref('/');
  var childRef = this.ref.child(this.props.params.username);
  this.bindAsArray(childRef,'notes');
},
componentWillUnmount: function() {
  this.unbind('notes');
},
render: function() {
...

And don't forget to change the rules from Realtime Database (because for now we are not authenticated)

{
  "rules": {
    ".read": true,
    ".write": true
  }
}
Max Orelus
Max Orelus
~ 8 years ago

I have my code structured exactly as you mentioned, but I keep getting this.bindAsArray is not a function. I've also changed my rules in firebase to true but I'm still not able to get pass this error.

Max Orelus
Max Orelus
~ 8 years ago

I just figured it out. I was writing my code with ES6. To get your code working with ES6 classes you need to import react-mixin and include it in your code like this:

reactMixin(Profile.prototype, ReactFireMixin);

Aleksey
Aleksey
~ 8 years ago

Thank you, that fixed the issue I had

Matt
Matt
~ 8 years ago

Thanks Russel

Shft
Shft
~ 8 years ago

THANKS Russell! Can we pin this some how?

Ben Polinsky
Ben Polinsky
~ 8 years ago

Do people really call 'li' tags "lie" tags?

YouYou
YouYou
~ 8 years ago

My Notes list on the web page are empty. I am using the last version of ReactFire and Firebase , so I have the next code, can you please tell me if there is any mistake ? Thanks


var Firebase = require('firebase'); var config = { apiKey: "XXXXXXXXXXXXXXXXXXXX", authDomain: "reactproj-XXXX.firebaseapp.com", databaseURL: "https://reactproj-XXXX.firebaseio.com", //storageBucket: "<BUCKET>.appspot.com", }; Firebase.initializeApp(config);

var Profile = React.createClass({ mixins: [ReactFireMixin], getInitialState: function(){ return { notes: [1,2,3], bio: { name: 'Tyler McGinnis' }, repos: ['a', 'b', 'c'] } }, componentDidMount: function(){ // V2 of reactfire // this.ref = new Firebase('https://reactproj-abba1.firebaseio.com/'); //var childRef = this.ref.child(this.props.params.username); // v3 of react fire: var childRef= Firebase.database().ref(this.props.params.username); this.bindAsArray(childRef, "Notes"); }, componentWillUnmount: function(){ this.unbind("notes"); },


kel
kel
~ 8 years ago

Russel's comment is still golden. #google #firebase #rules

Shawy
Shawy
~ 8 years ago

Hi Max, I got the same error as you mentioned. But I don't quite understand your solution, could you make it more detailed? thanks

Shawy
Shawy
~ 8 years ago

Just sort it out, thanks

Michael Wight
Michael Wight
~ 8 years ago

componentDidMount: function(){ this.ref = new Firebase('https://githubnote-taker.firebaseio.com'); var childRef = this.ref.child(this.getParams().username); this.bindAsArray(childRef, 'notes'); } This is what i have, but when i run this, my notes shows both the property and the value like this Notes: What a guy-JugSizVlM-1ijz6OPxZNew note-JugSlbdwr9jTIZZjurt What am i doing wrong? how do i get just the value like in the video? Hey! You have to change this "var childRef = this.ref.child(this.getParams().username);" with var childRef = this.ref.child(this.props.params.username)

Michael Wight
Michael Wight
~ 8 years ago

you need to first put this into your project. var ReactFireMixin = require('reactfire');

David
David
~ 8 years ago

Could you explain how you fixed it? I also am having trouble applying Max's solution.

Kylan Hurt
Kylan Hurt
~ 7 years ago

In case no one else has mentioned it: Google Chrome currently doesn't seem to be displaying the GUI for Firebase correctly (cannot find JSON import area, for example), but you can work-around it by using Firefox.

Mark Berry
Mark Berry
~ 7 years ago

Thank you!!

Alexius Hale-Dubuque
Alexius Hale-Dubuque
~ 7 years ago

I'm getting the error: "TypeError: Firebase is not a constructor". I've tried following the Firebase docs; but, I still get the error. My 'Profile.js' code is the same as the transcript. UPDATE: I reinstalled firebase with the following: 'npm install --save firebase@2.3.2 '. I'm no longer seeing the TypeError message; however, the Notes array is empty. I imported the JSON data object giving in the discussion. I can see the data in my firebase project; but, not in the notetaker app.

Nathan Brenner
Nathan Brenner
~ 7 years ago

At 7:40 I only got logged to the console the original notes value (from getInitialState) then an empty array. I looked at the rest of the comments on this thread, tried a bunch of the suggestions, and what ended up working was changing the rules in the database.

You can set rules to the database in your repo, or you can do it directly from https://console.firebase.google.com/project/${project name}/database/rules.

By default, the values are:

{
  "rules": {
    ".read": "auth != true",
    ".write": "auth != true"
  }
}

If you change it to this, it'll work:

{
  "rules": {
    ".read": "true",
    ".write": "true"
  }
}

Aside from that, I agree that the sidetrack to Firebase has been distracting from just expecting to learn React, but I've been meaning to get into Firebase just for the sake of things like prototyping apps.

The Firebase docs were a lot of help, particularly https://codelabs.developers.google.com/codelabs/firebase-web/#0

Also, Initially when I went to the project, I was using chrome and nothing was showing up on the ui, except the navbar, but it worked on Firefox. Sounded like someone else had this issue. I updated Chrome, and restarted my macbook pro, and it worked fine. Also worked fine on my windows 10 computer.

Gerard
Gerard
~ 7 years ago

i still keep getting this error:

TypeError: Firebase.initializeApp is not a function at Object. <code> var ReactFireMixin = require('reactfire'); var Firebase = require('firebase'); var config = { apiKey: "AIzaSyeJ7NFv1Q", authDomain: "github-notapp.com", databaseURL: "https://github-om", storageBucket: "github-notetakot.com", messagingSenderId: "90270" };

Firebase.initializeApp(config);

this.ref = Firebase.database().ref('/');
var childRef = this.ref.child(this.props.params.username);
this.bindAsArray(childRef,'notes');
</code>

this tutorial really should go into the firebase part as well... wanted to learn React and not firebase..

also changed my rules in firebase to: <code> { "rules": { ".read": "true", ".write": "true" } } </code>

update:

got the firebase notes to pull from my own fb-db but it wouldn't iterate properly until i re-read react's docs on iterating

var notes = this.props.notes.map(function(note, index){ return <li className="list-group-item" key={index}>{note}</li> this worked for me instead of {note['.value']}

also what made firebase work for me was changing not to:

{ "rules": { ".read": "true", ".write": "true" } }

but changing it to: { "rules": { ".read": "auth == null", ".write": "auth == null" } }

Brent Hoover
Brent Hoover
~ 7 years ago

I find this unexpected sideline into Firebase frustrating and a huge time-waster. And the links in the docs don't appear to work. (firebaseio.com is gone)

Sam
Sam
~ 7 years ago

I'm getting the same Firebase.intializeApp is not a function error. Can we get an official update on how to use Firebase?

Ryan
Ryan
~ 7 years ago

Just use local storage if you don't feel like messing around with firebase.

Igor Irianto
Igor Irianto
~ 7 years ago

Hey guys, I was having trouble with the Mixins. I started tutorial differently from Tyler's initial steps (I used create-react-app). If you are using ES6(ish) like me and couldn't get it to work, try this - after a few days of struggle, I finally got it work using re-base (coincidentally, Tyler is the author). Here is the meat code that made it work for me:

//profile.js
...
var base = Rebase.createClass({
  apiKey: <YOURAPIKEY>,
  authDomain: <YOURAUTHDOMAIN>,
  databaseURL: <YOURDBURL>,
  storageBucket: <YOURBUCKET>,
});
class Profile extends React.Component{
  constructor(props){
    super(props);
    this.state = {
      notes: ['whatever','you','want'],
      bio: {},
      repos: []
    }
  }
  componentDidMount(){
    base.syncState(this.props.params.username, {
      context: this,
      state: 'notes',
      asArray: true
    })
  }
  componentWillUnmount(){
    //this.unbind('notes');
    base.removeBinding(this.ref);
  }
  ... //the rest is similar as tutorial

And on Notelist, everything is the same except the mapping worked for me without .value: <li className="list-group-item" key={index}>{note}</li> Lastly, don't forget to check firebase rules

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

Hope that helps! Don't forget to npm install rebase

Mundaman
Mundaman
~ 7 years ago

Thank you Russell!!

Markdown supported.
Become a member to join the discussionEnroll Today