How Do I Fix ‘Uncaught TypeError: ReactFireMixin’ in React JS

When I first tried wiring up Firebase in a small react js app, I ran head-first into this error:

Uncaught TypeError: Cannot set property 'ReactFireMixin' of undefined

At first glance, it looked like I had messed up my imports or broken something in my build. After some digging, I realized the issue wasn’t just my code it was also about how ReactFireMixin works (or doesn’t work) in modern react js setups. Let me walk you through the problem, the fix, and then I’ll share a simple Firebase-backed todo app that helped me practice.

My First Attempt

Here’s the first version I wrote:

import react from 'react';
import {render} from 'react-dom';
import reactfire from 'reactfire';
import firebase from 'firebase';

class app extends react.component {
    render() {
        return <h1>
            hello bitches!
        </h1>
    }
}
var element = react.createelement(app, {});
render(element, document.queryselector('.app'));

And here’s my webpack config at that time:

module.exports = {
  entry: "./app/components/Main.js",
  output: { filename: "public/bundle.js" },
  module: {
    loaders: [
      {
        test: /\.jsx?$/,
        exclude: /(node_modules | bower_components)/,
        loader: 'babel',
        query: { presets: ['react', 'es2015'] }
      }
    ]
  }
}

Why the Error Happen

The ReactFireMixin error shows up because the version of reactfire I was pulling in expected React.addons to exist. But in modern React, there’s no addons property anymore. Mixins were used with the old React.createClass, and I was trying to use ES6 classes (class App extends React.Component). These two approaches don’t play together.

So, the reasons boiled down to:

  • The reactfire library was outdated for my setup.
  • Mixins aren’t supported in ES6 class components.
  • I also had multiple casing typos:
    • reactReact
    • react.componentReact.Component
    • app should be App (class names must be capitalized).
    • react.createelementReact.createElement.
    • document.queryselectordocument.querySelector.

In short: the modern way to do this is to ditch ReactFireMixin completely and talk directly to the Firebase SDK (or use the new reactfire hooks API).

The Fix Minimal Version

Here’s my working minimal version no mixins, just React and the Firebase SDK:

// src/index.jsx
import React from "react";
import { createRoot } from "react-dom/client";

// Firebase v9+ modular SDK
import { initializeApp } from "firebase/app";
import { getDatabase, ref, onValue } from "firebase/database";

// Firebase setup (use your own config values)
const firebaseConfig = {
  apiKey: "YOUR_KEY",
  authDomain: "YOUR_APP.firebaseapp.com",
  databaseURL: "https://YOUR_APP.firebaseio.com",
  projectId: "YOUR_APP",
  storageBucket: "YOUR_APP.appspot.com",
  messagingSenderId: "1234567890",
  appId: "1:1234567890:web:abcdef",
};
const app = initializeApp(firebaseConfig);
const db = getDatabase(app);

class App extends React.Component {
  state = { greeting: "hello there!" };

  componentDidMount() {
    const greetingRef = ref(db, "demo/greeting");
    onValue(greetingRef, (snap) => {
      const value = snap.val();
      if (typeof value === "string") this.setState({ greeting: value });
    });
  }

  render() {
    return <h1>{this.state.greeting}</h1>;
  }
}

const root = createRoot(document.querySelector(".app"));
root.render(<App />);

Updated Webpack Config

module.exports = {
  entry: "./src/index.jsx",
  output: { filename: "public/bundle.js" },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env", "@babel/preset-react"]
          }
        }
      }
    ]
  },
  resolve: { extensions: [".js", ".jsx"] }
};

If I Really Want ReactFire

The modern reactfire library doesn’t use mixins either. It uses providers and hooks:

import React from "react";
import { createRoot } from "react-dom/client";
import { FirebaseAppProvider } from "reactfire";
import { initializeApp } from "firebase/app";

const firebaseConfig = {/* ... */};

function App() {
  return <h1>Hi from ReactFire hooks</h1>;
}

const root = createRoot(document.querySelector(".app"));
root.render(
  <FirebaseAppProvider firebaseApp={initializeApp(firebaseConfig)}>
    <App />
  </FirebaseAppProvider>
);

With that, I can use hooks like useDatabase, useDatabaseObjectData, etc. No ReactFireMixin needed.

Practice Feature Firebase Todo App

To cement what I learned, I built a tiny todo list that reads/writes to Firebase:

import React from "react";
import { createRoot } from "react-dom/client";
import { initializeApp } from "firebase/app";
import { getDatabase, ref, onValue, push, set, update } from "firebase/database";

const firebaseConfig = {
  apiKey: "YOUR_KEY",
  authDomain: "YOUR_APP.firebaseapp.com",
  databaseURL: "https://YOUR_APP.firebaseio.com",
  projectId: "YOUR_APP",
  storageBucket: "YOUR_APP.appspot.com",
  messagingSenderId: "1234567890",
  appId: "1:1234567890:web:abcdef",
};
const fbApp = initializeApp(firebaseConfig);
const db = getDatabase(fbApp);

class App extends React.Component {
  state = { todos: {}, input: "" };

  componentDidMount() {
    const todosRef = ref(db, "demo/todos");
    onValue(todosRef, (snap) => {
      this.setState({ todos: snap.val() || {} });
    });
  }

  addTodo = async (e) => {
    e.preventDefault();
    const text = this.state.input.trim();
    if (!text) return;
    const listRef = ref(db, "demo/todos");
    const newRef = push(listRef);
    await set(newRef, { text, done: false, createdAt: Date.now() });
    this.setState({ input: "" });
  };

  toggleTodo = (id, done) => {
    const tRef = ref(db, `demo/todos/${id}`);
    update(tRef, { done: !done });
  };

  render() {
    const entries = Object.entries(this.state.todos);
    return (
      <div style={{ fontFamily: "sans-serif", maxWidth: 420, margin: "40px auto" }}>
        <h1>Firebase Todos</h1>

        <form onSubmit={this.addTodo} style={{ display: "flex", gap: 8 }}>
          <input
            value={this.state.input}
            onChange={(e) => this.setState({ input: e.target.value })}
            placeholder="Add a todo"
            style={{ flex: 1, padding: 8 }}
          />
          <button type="submit">Add</button>
        </form>

        <ul style={{ padding: 0, listStyle: "none", marginTop: 16 }}>
          {entries.length === 0 && <li>No todos yet.</li>}
          {entries.map(([id, t]) => (
            <li
              key={id}
              style={{
                display: "flex",
                alignItems: "center",
                gap: 8,
                padding: "8px 0",
                borderBottom: "1px solid #eee"
              }}
            >
              <input
                type="checkbox"
                checked={!!t.done}
                onChange={() => this.toggleTodo(id, t.done)}
              />
              <span style={{ textDecoration: t.done ? "line-through" : "none" }}>
                {t.text}
              </span>
            </li>
          ))}
        </ul>
      </div>
    );
  }
}

const root = createRoot(document.querySelector(".app"));
root.render(<App />);

Now I can add todos, toggle them, and see live updates straight from Firebase.

Final Thought

When I saw the ReactFireMixin error, my first instinct was that I mis-configured webpack or react js. The real lesson, though, was that ReactFireMixin is simply not meant for modern React. By switching to the Firebase SDK (or the updated reactfire with hooks), everything became cleaner, future proof, and easier to understand. If you hit this error, don’t waste time fighting with ReactFireMixin. Instead, embrace the new patterns. And if you really want to practice, try building something small like the todo app above. It’s the fastest way to learn.

Related blog posts