Code Monkey home page Code Monkey logo

redux-react-firebase's Introduction

redux-react-firebase

Use Firebase with React and Redux in ES6

Features

  • Suport for Firebase v3 (for older Firebase version use Branch 1.x)
  • Integrated into redux
  • Support small data ( using value ) or large datasets ( using child_added, child_removed, child_changed
  • queries support ( orderByChild, orderByKey, orderByValue, orderByPriority, limitToLast, limitToFirst, startAt, endAt, equalTo right now )
  • Automatic binding/unbinding
  • Declarative decorator syntax for React components
  • Support for nested props
  • Out of the box support for authentication (with auto load user profile)
  • Lots of helper functions

Install

$ npm install --save redux-react-firebase

Use

Include redux-react-firebase in your store

import {createStore, combineReducers, compose} from 'redux'
import {reduxReactFirebase, firebaseStateReducer} from 'redux-react-firebase'

const rootReducer = combineReducers({
  firebase: firebaseStateReducer
})
const config = {
  apiKey: '<your-api-key>',
  authDomain: '<your-auth-domain>',
  databaseURL: '<your-database-url>',
  storageBucket: '<your-storage-bucket>'
}
const createStoreWithFirebase = compose(
    reduxReactFirebase(config),
)(createStore)


store = createStoreWithFirebase(rootReducer, initialState)

In the components

import React, {Component} from 'react'
import PropTypes from 'prop-types'
import {connect} from 'react-redux'
import {firebase, helpers} from 'redux-react-firebase'

const {isLoaded, isEmpty, dataToJS} = helpers

@firebase( [
  'todos'
])
@connect(
  ({firebase}) => ({
    todos: dataToJS(firebase, 'todos'),
  })
)
class Todos extends Component {

  render() {
    const {firebase, todos} = this.props;


    const todosList = (!isLoaded(todos)) ?
                          'Loading'
                        : (isEmpty(todos) ) ?
                              'Todo list is empty'
                            : _.map(todos, (todo, id) => (<TodoItem key={id} id={id} todo={todo}/>) )

    return (
      <div>
        <h1>Todos</h1>
        <ul>
          {todosList}
        </ul>
        <input type="text" ref="newTodo" />
        <button onClick={handleAdd}>Add</button>
      </div>
    )
  }

}

API

See API

Example

You can see a complete example here

Tests

Mocha.js is used as test runner. To run the tests, run

npm run test

Contributors

redux-react-firebase's People

Contributors

codymorrison avatar davestevens avatar domiii avatar maxkomarychev avatar mrshll avatar prescottprue avatar rahavlussato avatar simonrozsival avatar tiberiuc avatar ubenzer avatar webbushka avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

redux-react-firebase's Issues

Advanced use question

Hi,

Thank you for creating this package. I have enjoyed using it so far.

There is a scenario I'm trying that I'm having trouble with. I have a component that requires an array of items for a specific user that comes from firebase. The list of item keys is listed under the user in firebase, so my initial watch looks something like:

@firebase(
    props => [
        `users/${props.userId}/items`
    ]
)

which gives me the list of item keys for that user. I then need to query those items themselves from firebase from /items by key. What is the preferred / recommended way to do this?

Initially I tried passing the array of keys to a lower component but that didn't work since @firebase() doesn't retrigger when props get updated, and the keys array was empty at first.

Thank you in advance.

Update to Firebase 3.x.x

Sad that the API has significant changes, but so things go. I've been using re-base but I love to play with your library. Do you have a plan for update?

[Question] How to fetch a single resource item based on its field value

In my firebase database I have a pages resource, which takes care of storing the data for the static pages of my app. It looks like this:

screen shot 2016-12-30 at 09 58 14

As you can see, I have a slug attribute, which I intend to match with the browser URL to retrieve the page data when the user lands on /about.

In the docs, I can see how to request a specific resource item using the ID, but how can I do it with a field value? In my case the slug value:

@firebase(
  props => ([
    `pages/${search by slug}`
  ])
)
@connect(
  (state, props) => ({
    todo: dataToJs(state.firebase, `pages/${search by slug}`)
  })
)

Outdated example

Hi Tiberiu,

The example uses configureStore from the store but it's not defined there.

import configureStore from './store'
const store = configureStore()

Can you post an example how to configure Firebase URL, since I am getting this error:

Uncaught Error: FIREBASE FATAL ERROR: Cannot parse Firebase url. Please use https://<YOUR FIREBASE>.firebaseio.com

Thanks!

firebase.intializeApp()

I follow all your setup and got firebase.intializeApp(). Look like the app don't initialize.

My Store

import { syncHistoryWithStore } from 'react-router-redux';
import { browserHistory } from 'react-router';
import { applyMiddleware, compose, createStore } from 'redux';
import createLogger from 'redux-logger';
import thunk from 'redux-thunk';
import { reduxReactFirebase } from 'redux-react-firebase'
import promiseMiddleware from 'redux-promise-middleware';
import rootReducer from './reducers';
import Config from '../config';

const middleware = [
  createLogger(),
  thunk,
  promiseMiddleware()
];

// Set var for all the middleware + redux chrome extension
const enhancers = compose(
  applyMiddleware(...middleware),
  window.devToolsExtension ? window.devToolsExtension() : f => f
);

const createStoreWithFirebase = compose(reduxReactFirebase(Config))(createStore);

const store = createStoreWithFirebase(rootReducer, {}, enhancers)

// Make the history work with browserHistory
export const history = syncHistoryWithStore(browserHistory, store);

// Make the hot reload work with Redux
if (module.hot) {
  module.hot.accept('./reducers', () => {
    const nextRootReducer = rootReducer;
    store.replaceReducer(nextRootReducer);
  });
}

export { store };

My Reducer

import { combineReducers, compose } from 'redux';
import { routerReducer } from 'react-router-redux';
import { reducer as formReducer } from 'redux-form'
import { firebaseStateReducer } from 'redux-react-firebase';

export default combineReducers({
  routing: routerReducer,
  form: formReducer,
  firebase: firebaseStateReducer
});

image

`reduxReactFirebase` function does not pass through `enhancer` argument of `createStore`

Per the redux docs for createStore, you can pass in an optional third argument for createStore, which is commonly used to apply middlewares. Following the example in the README, this doesn't work as expected because reduxReactFirebase only returns a createStore function that accepts two arguments.

For example, when using the thunk middleware:

import {createStore, combineReducers, compose, applyMiddleware} from 'redux'
import {reduxReactFirebase, firebaseStateReducer} from 'redux-react-firebase'
import thunkMiddleware from 'redux-thunk'

const rootReducer = combineReducers({
  firebase: firebaseStateReducer
})
const config = {
  apiKey: '<your-api-key>',
  authDomain: '<your-auth-domain>',
  databaseURL: '<your-database-url>',
  storageBucket: '<your-storage-bucket>'
}
const createStoreWithFirebase = compose(
    reduxReactFirebase(config),
)(createStore)

const middlewares = applyMiddleware(thunkMiddleware)
const store = createStoreWithFirebase(rootReducer, initialState, middlewares)

the middlewares argument does not actually get passed through to redux's createStore function.

User profile is undefined

I'm following the auth example, but the user profile comes as undefined, although the auth object is fine:

@firebase()
@connect(
  	(state, props) => ({
		user: pathToJS(state.firebase, 'auth'),
		profile: pathToJS(state.firebase, 'profile')
  	})
)
const createStoreWithFirebase = compose(
    reduxReactFirebase(firebaseConfig, {userProfile: 'users'}),
	window.devToolsExtension ? window.devToolsExtension() : f => f
)(createStore);

I've also tried without the devTools stuff, but no luck.

I do have the 'users' node in my Firebase database, although no ID is being created in the 'users' node when using firebase.createUser(credentials, { name.value }), which might be the real cause of the issue...

BTW, in the docs says: "profile if initialized with userProfile support then profile will be saved into ${userProfile}/${auth.uid}", so that means it should create the new key in the 'users' node.

I've also tried to rename userProfile to profile in the store, but it doesn't make any effect:

reduxReactFirebase(firebaseConfig, {profile: 'users'}),

Rename or close repo

SOOOOO many time my coworkers and I have confused this repo for the real one. GO AWAY ๐Ÿ‘Ž I just spent a half hour reading the wrong docs. You owe me money ๐Ÿ’ฐ

Using geoFire.js with redux-react-firebase

Hi, I am using your repository for all functionalities with my app. But geoFire seems to be an integral part of my app and I am unable to understand how to use both in sync with redux.

Please suggest!

TIA

[Question] How to make subsequent firebase requests with values received from a previous request?

Hi there,

I'm having some difficulties trying to make queries a bit more complex than the ones explained in the API docs and I was wondering if the library can handle those scenarios and perhaps I'm missing something.

My target is to request for all the files, subjects, levels and users associated to a specific course. At the moment, due to the querying difficulties, I have to download everything and then use loops to find the right info. This is far from ideal, as the app will not perform well as it scales.

This is how my queries look like:

@connect(
  	(state, props) => ({
    	        course: dataToJS(state.firebase, 'courses'),
		levels: dataToJS(state.firebase, 'levels'),
		subjects: dataToJS(state.firebase, 'subjects'),
		users: dataToJS(state.firebase, 'users'),
		files: dataToJS(state.firebase, 'files'),
		userID: state.mainReducer.user ? state.mainReducer.user.uid : '',
		//featuredImage: state.course.featuredImage ? state.course.featuredImage : '',
		courseID: props.course ? props.course[Object.keys(props.course)[0]].code : '',
		userData: dataToJS(state.firebase, `users/${state.mainReducer.user ? state.mainReducer.user.uid : ''}`),
  	})
)
@firebase(
  	props => ([
    	        `courses#orderByChild=slug&equalTo=${props.params.slug}`,
		'levels',
		'subjects',
		//`subjects#orderByKey&equalTo=${props.course ? props.course[Object.keys(props.course)[0]].subjects : ''}`,
		'users',
		'files',
		//`files#orderByChild=featuredImage&equalTo=${props.featuredImage}`
		`users/${props.userID}`
  	])
)

As you can see, I can get the user ID from my custom reducer, mainReducer, which gets it from the authentication module. That's fine, the problem I find is when I want to use a prop like props.course (which receives the data from firebase) to make subsequent calls to firebase, i.e. to retrieve the files or subjects of that specific course ID. Is this possible at all? I don't seem to find anything that comes from firebase inside the state and props in the @connect. The only props available there are the ones I set using my custom mainReducer.

I though of setting the course data in my mainReducer so I could access it in the @connect and use it to make other firebase requests, but it seems like an overkill to save something in the state tree that has already been saved...

I hope it does make sense. Thanks in advance for your time!

Could you give me feedback on my previous solution?

It was a basic Firebase middleware:

const fbMiddleware = store => next => action => {
    const result = next(action);
    if(action.type!=='SET_STATE'){
        firebaseRef.update(store.getState().toJS())
    }
}


const  store = createStore(reducer, applyMiddleware(thunk, fbMiddleware))

Can't get my firebase data.

Hi, I can't get my data from firebase using @connect. Also I'm using react router to pass my params.

There is my code :

@firebase( [ 'fishes' ]) @connect( (state, props) => ({ fishes: dataToJS(state.firebase,/${props.params.storeId}/fishes) }) )

props.params.storeId is equal to 'itchy-drab-leaves' from the url.

My firebase url look like this : https://fishes-store.firebaseio.com/itchy-drab-leaves

but I can send data to firebase with push :
firebase.push(${this.params.storeId}/fishes, data)

What I'm doing wrong ?

Thanks !

this.props.firebase undefined, this.props.store.firebase is not.

When I follow the example as close as possible, I'm stuck when I try to define:

{ firebase } = this.props

From exampe: https://github.com/tiberiuc/redux-react-firebase/blob/master/example/App.js

My component has no this.props.firebase, it does have this.props.store.firebase

My reducer (reducers/index):

Redux                    = require 'redux'
{ combineReducers }      = Redux
{ firebaseStateReducer } = require 'redux-react-firebase'
visibilityFilter         = require './visibilityFilter'

combinedReducer = combineReducers({
  visibilityFilter: visibilityFilter,
  firebase: firebaseStateReducer
})

I assume that's where this.props.store.firebase comes from.
Then in the file where I put the Provider component:

reducers = require './reducers/index'

firebaseRef           = reduxReactFirebase('https://xxx.firebaseio.com/', { 'userProfile', 'users'} )
composedStore         = compose(firebaseRef)(createStore)
store                 = composedStore(reducers , {})
...
// then later:
 ReactDOM.render(
    <Provider store={store}>
           <App store={cubeStore.getState()} />
    </Provider

Then, when I inspect Provider with React devtools:

   Object 
    dispatch: dispatch(action)
    firebase: Object 
    getState: getState()
    replaceReducer: replaceReducer(nextReducer)
    subscribe: subscribe(listener)
    Symbol(observable):observable()

This looks good, and firebase contains _, helpers, and ref

But this is in this.props.store.firebase, not in this.firebase like the example suggests.

However, then I try to connect firebase to one of my containers, and it gets a context store, and also this.state.storeState which is not documented anywhere.

{ firebase, helpers }           = require 'redux-react-firebase'
{ isLoaded, isEmpty, dataToJS } = helpers

firebase = firebase(['test']).bind(this)
connect(({firebase}) => ({
    test: dataToJS(firebase, 'test'),
  })
).bind(this)

https://github.com/tiberiuc/redux-react-firebase/issues/20

this.state.storeState contains _root and a size prop, in that Connected element.

Now main problem is, that I can't use firebase.set() like intended from the examples, and I'm sure I shouldn't manually extract it from the context.store.firebase.helpers?

(As a sidenote, while browsing through the source, I don't understand the import Firebase from 'firebase' in https://github.com/tiberiuc/redux-react-firebase/blob/master/source/index.js, I don't see it is ever used there?)

orderByChild parses to int

Hi guys -

First off great work - I'm finding the library to be super useful.

I do notice that you force values to ints here. When I to an orderByChild("something").equalTo("someString") is doesn't work - I mean the children are strings even though in some cases the strings do actually parse as ints. Anyway, I can take out the parseInt and things work as I expect them to. What do you think about an option to not coerce to int? Given that you're using query strings, maybe something like doNotParse=1??

Logout erases all data

When the user logs out of the app, all the data is removed by the reducer. This does not work for me and I think this behaviour isn't really that convenient for other purposes. I want some of the data to remain in the state and I cannot think of a good way of achieving that.

Issue when bunding with webpack

I got the following errors when trying to use with webpack. I tried using both noParse as well as setting an alias to both the source folder and the build folder.

screen shot 2016-06-04 at 2 16 17 am

I was able to get it working by installing bluebird and immutable into my project, but it might be nice to make those become dependencies or be part of the docs somewhere.

child_remove listening

@firebase((props) => {
  return [
    [`${props.userId}/friends`]
  ]
})

this code not working. "Invalid path"
I need child_remove listening

Firebase v3

Feature Request: v3 of Firebase Library

I was having problems connecting to new Firebase instances using the old v2.4.x library. Any thoughts on switching to the new API soon?

Have done a few full apps with V3 and redux, so I am willing to help. Let me know if you agree, and I will work on making a PR.

ES6/7 Decorator alternative

I see in the example (https://github.com/tiberiuc/redux-react-firebase/blob/master/example/App.js)

@firebase()

and then later:

@firebase( [
  '/todos', // if list is too large you can use ['/todos']
])

I'm not sure why this happens twice, and what the decorator does exactly, and what the alternative would be with ES5.

Also, the comment // if list too large you can use ['/todos'] I don't understand what this means, can you elaborate? (there is no difference in '/todos')

Sorting doesn't work

I have a structure like that
screenshot 2017-05-08 17 34 19

Defined @firebase(['/chats#orderByChild=timestamp']) and my data doesn't sort, but that works if I tried to do it directly by firebase API

import firebase from 'firebase';
const userMobilePath = '/chats';

    firebase.database().ref(userMobilePath)
      .orderByChild('timestamp')
      .on('value', function(snapshot) {
        const data = [];

        snapshot.forEach(function(child) {
          data.push(child.val());
        }.bind(this));

        data.reverse().map(function(val) { console.log('val', val.title); });
    });

Could you check and add some sorts methods to your example?

Authentication does not work for me

First, thank you for this library, very useful!

I'm trying to implement Email/Password login based on the example provided in AppWithAuth.js. I created a dedicated component Login.js (see code below) and I'm not using decorator pattern so I changed the code a bit.

The issue is that I always get a 'auth/network-request-failed' error code. There is no corresponding network request. I did some digging, found this thread that suggests that React checks the error code synchronously: https://groups.google.com/forum/#!topic/firebase-talk/yeo8z7nu_K4

I'm not sure I'm not doing something wrong here. The rest works, I connect/read/update my data fine.

Below my code:
import React, {Component} from 'react'
import {firebase, helpers} from 'redux-react-firebase'
import {connect} from 'react-redux'

const {pathToJS} = helpers

class Login extends Component {
constructor(){
super()
this.state = {loading:false}
}

render(){
const {firebase, authError} = this.props

const handleLogin = () => {
  const {email, password} = this.refs

  const credentials = {
    email: email.value,
    password: password.value
  }

  firebase.login(credentials)

  this.setState({ 'loading':true})
}

const error = (authError) ?
                  authError.toString()
                : (this.state.loading) ?
                          'loading'
                        : ''

return(
  <div>
    <h1>Login</h1>
    <input type='email' placeholder='Email' ref='email' /><br/>
    <input type='password' placeholder='Password' ref='password' />
    <p>{error}</p>
    <div onClick={handleLogin}>Login</div>
  </div>
)

}
}
const LoginWrapper = firebase()(Login)

export default connect(
({firebase}) => (({firebase}) => ({ authError: pathToJS(firebase, 'authError') }) )
)(LoginWrapper)

How to catch errors on Login?

firebase.login() does not seem to change the redux state of authError. How do I know if the user has inputted an invalid username / password?

FirebaseConnect: type specification of context `store` is invalid

Looks like the store is not being set correctly in the FirebaseConnect contextTypes (source/connect.js Line 123). Getting this error:

Warning: FirebaseConnect: type specification of context `store` is invalid; the type checker function must return `null` or an `Error` but returned a function. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).

Expecting:

FirebaseConnect.contextTypes = {
  store: PropTypes.object.isRequired
}

Instead of Line 123:

FirebaseConnect.contextTypes = {
    store: function () {
      return PropTypes.object.isRequired
    }
  }

Testing with [email protected]

doNotParse: Undocumented, often unwanted behavior

For some reason, equalTo query arguments sometimes get parsed as integers, even if they are not integers, leading to troublesome side-effects.

I used orderByChild in combination with equalTo on user ids, sending me on a two-hour bug hunt where the query worked for some users and not work for others; only to find out that for this query combination, the equalTo handler in actions.js, by default, parses their parameter as integer using parseInt, like so:

case 'equalTo':
  let equalToParam = !doNotParse ? parseInt(param[1]) || param[1] : param[1]

This sort of logic has multiple problems:

  1. It does not work for strings that begin with integers, such as firebase-generated ids: parseInt('11asfkvvjjjj--add') actually returns 11. That's right, parseInt ain't a quitter; if it doesn't work for the whole thing, it settles for any number prefix in the string.
  2. It does not work for 0: parseInt("0") || "0" actually returns the string "0" instead of number 0.

I propose a simple fix, borrowed from this StackOverflow discussion on integer string validation:

function isIntString(val) {
    return val === "" + ~~val;
}
// ...
let equalToParam = (!doNotParse && isIntString(param[1])) ? parseInt(param[1]) : param[1];

It's not perfect but certainly a lot better. Maybe just working with numbers in general, rather than int only would be better?

PS: There are a few more questions related to the rationale behind this design decision:

  1. You only assume that integers need parsing. What about floats or other sorts of special values that might have accidentally ended up string-encoded?

  2. And also: why is doNotParse not the default? Shouldn't special parsing behavior that might make your queries not behave the way they would when using vanilla firebase, be opt-in, rather than opt-out?

Docs unclear/suggestion

Going into this, I thought this was going to be similar to redux-storage-engine-localstorage, which is my fault, but perhaps partially the documentations'.

I'm curious why there are no dispatchers used, at least not in the user's code, only in the src. The code-example omits the fact that direct calls to Firebase are made, and then changes would come back to the store which works, but I don't understand this approach as it circumvents a more "reduxy" way of having dispatchers initiate changes, to avoid bugs, inconsistencies and confusion.

It's also very confusing when the example code is missing half of the code that makes it work, and misleading, as from the example-code I assumed dispatches where used when making changes.
For example the handleAdd function definition is not shown, only in example source, where it turns out it does a plain firebase.push, which is fine, but not what I expected when I read the initial docs.

What I expected was, I dispatch an action, it changes something in the local store, and at the same time updates it in firebase. The main problem is when I use multiple middlewares, like localstorage, I want to prevent having to dispatch and update firebase everytime, these should be unified.

I understand that how it is now, listeners are being placed, so the top store is always up to date.

What I would suggest is at least one example of how to use this in conjunction with dispatch, instead of calling firebase directly, like mentioned above, having this work with some sort of middleware and use set push and remove.

Or an example of how to use it with mapStateToProps, mapDispatchToProps ?

Maybe I'm completely wrong about these approaches, but it's just an idea..

Redux Dev Tools

Will this work with redux dev tools and redux-react-router?

Rationale behind `data` path?

From the beginning this confused me a bit: For some reason, this library (and I think I also saw it in other libraries) gave special significance to the /data path, specifically by offering the dataToJS convenience helper function. From what I understand, the /data path has no special significance to Firebase per se, so, if I am not utterly wrong, this is based on some sort of convention, isn't it?

Seeing how your library gives special attention to the /data path, references to documents which propose the convention of structuring your data in Firebase like this would be greatly appreciated, not sure if you or anyone else could provide those?

(Slightly off-topic: In general, any sort of list of resources and conventions that help new-comers better structure their data right from the start, would love to hear about it :) )

server side rendering

when trying to call createStoreWithFirebase on the server I get this error.

export const createStoreWithFirebase = compose(
    reduxReactFirebase(config),
)(createStore);

I can recreate the error if I import firebase from the server

import * as firebase from "firebase"
console.log(firebase);
ReferenceError: self is not defined
    at eval (eval at ./node_modules/firebase/messaging.js (/srv/eat/www/server.bundle.js:1167:1), <anonymous>:25:367)
    at eval (eval at ./node_modules/firebase/messaging.js (/srv/eat/www/server.bundle.js:1167:1), <anonymous>:37:614)
    at eval (eval at ./node_modules/firebase/messaging.js (/srv/eat/www/server.bundle.js:1167:1), <anonymous>:38:4)
    at Object../node_modules/firebase/messaging.js (/srv/eat/www/server.bundle.js:1167:1)
    at __webpack_require__ (/srv/eat/www/server.bundle.js:21:30)
    at eval (eval at ./node_modules/firebase/firebase-browser.js (/srv/eat/www/server.bundle.js:1160:1), <anonymous>:12:1)
    at Object../node_modules/firebase/firebase-browser.js (/srv/eat/www/server.bundle.js:1160:1)
    at __webpack_require__ (/srv/eat/www/server.bundle.js:21:30)
    at eval (eval at ./node_modules/redux-react-firebase/build/compose.js (/srv/eat/www/server.bundle.js:4962:1), <anonymous>:7:17)
    at Object../node_modules/redux-react-firebase/build/compose.js (/srv/eat/www/server.bundle.js:4962:1)
ReferenceError: self is not defined
    at eval (eval at ./node_modules/firebase/messaging.js (/srv/eat/www/server.bundle.js:1167:1), <anonymous>:25:367)
    at eval (eval at ./node_modules/firebase/messaging.js (/srv/eat/www/server.bundle.js:1167:1), <anonymous>:37:614)
    at eval (eval at ./node_modules/firebase/messaging.js (/srv/eat/www/server.bundle.js:1167:1), <anonymous>:38:4)
    at Object../node_modules/firebase/messaging.js (/srv/eat/www/server.bundle.js:1167:1)
    at __webpack_require__ (/srv/eat/www/server.bundle.js:21:30)
    at eval (eval at ./node_modules/firebase/firebase-browser.js (/srv/eat/www/server.bundle.js:1160:1), <anonymous>:12:1)
    at Object../node_modules/firebase/firebase-browser.js (/srv/eat/www/server.bundle.js:1160:1)
    at __webpack_require__ (/srv/eat/www/server.bundle.js:21:30)
    at eval (eval at ./node_modules/redux-react-firebase/build/compose.js (/srv/eat/www/server.bundle.js:4962:1), <anonymous>:7:17)
    at Object../node_modules/redux-react-firebase/build/compose.js (/srv/eat/www/server.bundle.js:4962:1)

at eval (eval at ./node_modules/redux-react-firebase/build/compose.js(/srv/eat/www/server.bundle.js:4962:1), <anonymous>:7:17)
line 7 on compose.js requires firebase and it errors when ran on the server

fetch data once without listen

hi i saw in the docs that this one is In the future (Firebase queries),
do you have any estimation for this one ?
after i tried couple of packages of react and firebase integration i can say that your's package is
the most efficient one because its include redux in perfect way, but fetching data is basic feature that is missing.

Support multiple apps

Currently, the reduxReactFirebase call is very opinionated on how to use firebase, it attaches itself to the store as firebase and, in addition, also attaches itself to the global firebase module. That is bad style, and makes it entirely monolithic.

As explained in the official documentation, you can work against the database of a specific app by simply storing the reference to the object from the return value of the initializeApp call, and then call database() on that, instead of calling it directly on the default firebase object.

dataToJS only works for explicitely defined paths

Assuming I have:

@firebase((props, firebase) => ([
  '/quizzes',
  '/quizProblems'
]))

and I have an object /quizzes/abc in the database,

then:

dataToJS(firebase, '/quizzes/abc')

will return undefined.

However:

dataToJS(firebase, '/quizzes/').abc

works.

I would assume this is because you are not actually converting nested Firebase data into immutables. I absolutely agree that this is a good thing - in terms of performance, as well as in practical terms, considering that you are not supposed to change firebase-managed data directly at all, but rather commit any changes through the firebase API instead.

Either way, this and general data management guidelines should be explicitly stated in the docs, while also hinting at _.get to directly access firebase data at a given path.

Getting the redux mirror of the local firebase cache to become readonly, would be an even bigger plus! :)

How to log a user in when testing?

I'm trying to test a component whose layout changes depending on whether a user is logged in. My Mocha tests looks like this:

import {Provider} from 'react-redux';
import TestUtils from 'react-addons-test-utils';
import expect from 'expect.js'
import newStore from './store';
import MyComponent from './MyComponent.jsx';

describe('MyComponent', function() {

  context('when the user is logged in', function() {
    var component;

    beforeEach(function() {
      // initialize the Redux store
      var store = newStore({ gameID: 'a001' });

      // log a user in programmatically - but how to do it?

      // render the component under test
      component = TestUtils.renderIntoDocument(
        <Provider store={store}>
          <Game />
        </Provider>
      );
    });

    it("should show the user's name", function() {
      var playerNameDisplay = TestUtils.findRenderedDOMComponentWithClass(
        component, 'player-name'
      );
      expect(playerNameDisplay.textContent).to.be('My Name');
    });

    /* and all the rest of the tests... */
  });
});

I'm not really sure how to log a user in during test setup. First I tried to just set the user profile by initializing the store with a profile in place:

beforeEach(function() {
  // initialize the Redux store - with a profile set!
  var store = newStore({ gameID: 'a001', firebase: { profile: { name: 'My Name' }}});

  // render the component under test
  component = TestUtils.renderIntoDocument(
    <Provider store={store}>
      <Game />
    </Provider>
  );
});

but when the component under test rendered, the profile data was gone. Looks like it gets reset.

Then I tried to find a way to call the createUser and login methods provided by redux-react-firebase in the test setup, but couldn't figure out how to get a reference to the object that has those methods:

beforeEach(() => {
      // initialize the Redux store
      var store = newStore({ gameID: 'a001' });

      // log a user in programmatically
      var credentials = {
        email: '[email protected]',
        password: 'a'
      };
      var firebase = // but how to get a reference?
      firebase.createUser(credentials, { name: 'My Name' });
      firebase.login(credentials);

      // render the component under test
      component = TestUtils.renderIntoDocument(
        <Provider store={store}>
          <Game />
        </Provider>
});

Is there a way to get a reference in my test setup to the object createUser and login are defined on? Or am I going about logging a user in all wrong? Any guidance would be very helpful, I'm stuck.

Why was oauth support removed?

Despite the fact that on the 1.x branch, all authentication methods were supported, the current version only provides signInWithEmailAndPassword.

Seems like quite a big step backward :/

I am guessing, you guys could not find the time to update for all firebase v3 features?

It's not too big a deal since onAuthStateChanged is being monitored. It's just that LOGIN_ERROR won't be dispatched in case signInWithPopup or signInWithRedirect throw any errors.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.