GithubHelp home page GithubHelp logo

n6g7 / redux-saga-firebase Goto Github PK

View Code? Open in Web Editor NEW
284.0 5.0 57.0 15.41 MB

A redux saga integration for firebase.

Home Page: https://redux-saga-firebase.js.org/

License: MIT License

JavaScript 100.00%
firebase redux redux-saga saga

redux-saga-firebase's Introduction

⚠️ This project isn't maintained

I unfortunately don't have time to maintain this project anymore. I'd be happy to share commit access with anyone interested in taking over the project, get in touch if you'd like to revive rsf!


redux-saga-firebase

CircleCI npm version Coverage Status

A redux-saga integration for firebase.

Quick start

Install with:

yarn add redux-saga-firebase

Initialize a firebase app and instantiate redux-saga-firebase:

import firebase from 'firebase'
import '@firebase/firestore' // 👈 If you're using firestore
import ReduxSagaFirebase from 'redux-saga-firebase'

const myFirebaseApp = firebase.initializeApp({
  apiKey: 'qosjdqsdkqpdqldkqdkfojqjpfk',
  authDomain: 'my-app.firebaseapp.com',
  databaseURL: 'https://my-app.firebaseio.com',
})

const reduxSagaFirebase = new ReduxSagaFirebase(myFirebaseApp)

You can now use reduxSagaFirebase methods in your sagas:

function* syncSaga() {
  yield fork(reduxSagaFirebase.database.sync, 'todos', {
    successActionCreator: syncTodos,
  })
}

Make sure your client provides a implementation of fetch, either natively or via a polyfill (whatwg-fetch is a pretty good one).

API

Authentication

Database

Firestore

Functions

Messaging

Storage

Contributing

  • Clone
  • Link lib to example site:
    • yarn link in root directory
    • yarn link redux-saga-firebase in example directory
  • Run tests: yarn test

redux-saga-firebase's People

Contributors

brunogodefroy avatar bugcloud avatar charlottebretonsch avatar dependabot-preview[bot] avatar elco45 avatar greenkeeper[bot] avatar hamidzr avatar juanialt avatar n6g7 avatar ragnarhal avatar ryansully avatar sarovin avatar ted-nz avatar tomclose 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

redux-saga-firebase's Issues

How can I catch "errors" that result from purposely checking a path that shouldn't exist?

I'm using to double check everything that should be deleted from the server is deleted. I'm doing that like this:

yield call(rsf.storage.getDownloadURL, downloadUrlToCheck)

This call will result in an error if there's nothing at that downloadURL, as it should, but what I'd love is if I could catch it and log it as an info instead of an error

Using a try/catch, I haven't been able to do this. Honestly, I forget exactly why, it's been quite a long time since I wrote the code, but I think my conclusion was that RSF is catching the error before I can. Could be totally off.

So I'm wondering if there's some way around this issue, or if there's something I can do that I'm overlooking.

 'storage/object-not-found',
  message_: 'Firebase Storage: Object \'users/M2i5teuZdjTX821ObPwksb8uvVo2/files/someFileName\' does not exist.',

ERROR: regeneratorRuntime is not defined

After including Redux Saga Firebase as the docs suggest, I am getting a regeneratorRuntime is not defined error in my Chrome console. Specifically it is complaining about the first generator function in my saga file.

function* logIn(action) {
  ...
}

I was actually getting this error before but resolved it by adding import 'regenerator-runtime/runtime' in my saga file.

Is there something else I need to do to prevent this error?

weird issue with channel

Hi,

We have an interesting issue, when we login to the app very first time we don't get any channel updates. The example of the code we have is the following:

function* getSubscriptionStatus() {
  // waiting for root path to become available plus giving a chance to fully run
  try {
    yield delay(5000);
    const rootPath = yield select(selectRootPath);
    const channel = yield call(rsf.database.channel, `${rootPath}${dbPaths.configStatus}`);
    while (true) {
      const { value: status } = yield take(channel);
      if (status) {
        yield put(subscriptionStatus(status === 'active'));
      }
    }
  } catch (e) {
    return e;
  }
}
export default function* rootSaga() {
  yield [
    // omitted
    fork(getSubscriptionStatus),
  ];
}

If I logout and login back to the firebase it starts to work, any idea how to resolve this ?

Many Thanks.

Listening to the same channel a 2nd time does not work

I have this code to listen to my channel:

  yield all([
    reduxSagaFirebase.database.sync(
      `users/${user.id}/orders`,
      userActions.historyFetchSuccess
    )
  ]);

This runs every time a user signs in.

However, when I:

  1. Sign in with User 1
  2. Sign out
  3. Sign in with User 2
  4. Sign out
  5. Sign in with User 1

The saga does not yield on the last step. My hunch is because it has listened to that path before, and breaks for some reason if it tries to listen to it again

If I change the path to something unique (just to prove that this is the issue), it works every time:

 const date = moment().valueOf(); // just current time in seconds
 yield all([
   reduxSagaFirebase.database.sync(
     `users/${user.id}/orders-${date}`,
     userActions.historyFetchSuccess
   )
 ]);

Use more than one project

Can redux-saga-firebase use more than one project? We are using the auth and firestore sections and it's working well with a single project.

We are trying to open a second project and are giving the init a second name.. seems to start, but the data is still the to other project. Very odd.

admin.initializeApp(config, 'secondProject');

Has anyone had success with this?

AaD I can receive null or undefined values via database channel.

Redux-saga does not support null or undefined values being emitted in a channel:

Note: You need to sanitize your event sources as to not pass null or undefined through the event channel. While it's fine to pass numbers through, we'd recommend structuring your event channel data like your redux actions. { number } over number.

The recommended solution is to format the channel like a redux action (object with keys). We could have a "data" key to pass the result.

Demo error on file upload

Clicking on the Sind File button in the demo page throws

Uncaught TypeError: this.input.click is not a function
    at FileButton.onClick (FileButton.js?3181:26)
    at Object.Ja (react-dom.production.min.js?8b5e:26)
    at Object.invokeGuardedCallback (react-dom.production.min.js?8b5e:25)
    at Object.invokeGuardedCallbackAndCatchFirstError (react-dom.production.min.js?8b5e:25)
    at Za (react-dom.production.min.js?8b5e:30)
    at cb (react-dom.production.min.js?8b5e:32)
    at gb (react-dom.production.min.js?8b5e:32)
    at Array.forEach (<anonymous>)
    at ab (react-dom.production.min.js?8b5e:31)
    at lb (react-dom.production.min.js?8b5e:34)

OS: MacOS High Sierra 10.13.2
Browser: Chrome

Support database queries for sorting/filtering

Currently all of the database methods accept a path string to define the Firebase database reference. Because of this, sorting and filtering features are not supported. If a ref could be passed to the method instead of a path, sorting and filtering could be defined before performing the database operation.

Ideally the database methods would support either a path string or a ref, either by separate methods or combined in the same ones?

Redux-saga 1.0.0 beta support?

Redux-saga seems unlikely to be changing much, but there are some minor changes.

1.0.0 makes debugging a whole lot easier, but it seems to conflict with this package unfortunately. Are there official plans to update this library?

Thanks!

Child_added supported in sync? -> Adding to Documentation

First of all: Great Work!

I'm currently wondering which data is transferred on a sync in case a child was added/remove/... in the realtime database?
Is the whole data/ref transferred or only the delta?

Many thanks for clarification.

Call a function running locally

Is there a way to call a function running locally?

Instead of https://us-central1-project-id.firebaseapp.com/ it would run at say http://localhost:5000/.

function* callFunction() {
  // Will make a POST request to https://us-central1-project-id.firebaseapp.com/sayHello?name=Alfred
  // with custom headers

Add listener in loop

Hi,

How I can add firebase on('value') listener in a loop. For example :
I have user path in firebase and I want to attach listeners for specific users only, I have an array of use keys.

firestore.addDocument need to assign specific document id.

Current docs show:

Adds a new document to this collection with the specified data, assigning it a document ID automatically

Is there any current or planned means to assign a specific id? For example: we want to create a staff document that matches to the auth document with the same id.

Using the library Universally

Loved the library. the simplicity and how it works in sync with Firebase is just marvellous.

I want to use it, but my library uses Universal or Isomorphic Node JS with React. So I was wondering how do I setup the RSF library so that preloaded server-side functions can be called with this so that we can serve data universally through the static functions thus decreasing initial load-time drastically.

Also what would be a way to move the firebaseconfig part to server so that we could use something like firebase-admin

uncaught exception when path does not exist

working on react-native and react-native-firebase,
everything works pretty well, but I found this use case,
I'm not sure how it behaves on the web, but in react-native, you get an
uncaught exception when using databaes.read with a path that doesn't exist.
The reason is that result.val() is not a function if result.exists() is false.

I did open a pull request
with the changes so that if the path doesn't exist read returns null.
Alternatively, if you still want to produce an exception I'd then specify the error,
so we can handle properly the case.

[best-practice] database.channel

Hello,

thanks for your great work, I fell in love with it :)

I have questions regarding best practice on channels.

  • How do you handle paths that contains a variable set only when auth is complete (e.g user.uid) ?
  • How do you handle the unregistration => registration when changing user since syncDashboardsSaga is ony called once?

The following code does not work because user does not exist when loading the app (only populated when auth.channel respond)

function* syncDashboardsSaga() {
  const user = yield select(state => state.auth.user);
  const channel = yield call(rsf.database.channel, `dashboards/${user.uid}`);

  while (true) {
    const { value } = yield take(channel);
    yield put(actions.dashboardsUpdate(value));
  }
}

export default function* dashboardsRootSaga() {
  yield fork(syncDashboardsSaga);
}

Keep auth when reloading browser

For the example auth flow, when someone refreshes the browser, Firebase actually doesn't lose the auth, but this saga flow needs a tweak to capture that: just put a loginSuccess action after the yield put(syncUser(user)), as below:

function * syncUserSaga () {
const channel = yield call(rsf.auth.channel)
while (true) {
const { user } = yield take(channel)
if (user) {
yield put(syncUser(user))
yield put(loginSuccess())
}
else yield put(syncUser(null))
}
}

'child_added' fires at startup for every item online?

I've got code like this, but it fires for every single item on Firebase at startup. Is this the way it should be operating? How can I prevent this without removing the channel entirely?

function* childAddedListener() {
  try {
    const path = yield call(getPath, 'items');
    const childAddChannel = yield call(rsf.database.channel, path, 'child_added');
    while (true) {
      try {
        const { value: item } = yield take(childAddChannel);
        yield put(someAction(item));
      } catch (err) {
        log.error(err);
      }
    }
  } catch (err) {
    log.error(err);
  }
}

Firebase documentation states:

Child Added

The child_added event is typically used when retrieving a list of items from the database. Unlike value which returns the entire contents of the location, child_added is triggered once for each existing child and then again every time a new child is added to the specified path. The event callback is passed a snapshot containing the new child's data. For ordering purposes, it is also passed a second argument containing the key of the previous child.

But I swear when I had firebase implemented outside of sagas, I did not download all the contents of the path when listening for additions.

Thanks very much!

More Firebase-centric documentation

First of all, I love the direction that this project is going, and the attention to testing and coverage!

As a dev that uses Firebase across a number of projects, I'm more used to seeing Firebase nomenclature for its API, such as on() and once(), so finding their equivalents here took a bit of searching around. I noticed that somewhat already for rsf.channel(), whose doc refers to Reference.on() for event argument values, but it's less clear or obvious for other other methods like rsf.authChannel() wrapping onAuthStateChanged() with an event channel (which is awesome btw), which I wouldn't have known unless I looked at the source code.

So question: could the documentation include notes about which Firebase API features are analogous to corresponding methods in RSF?

I know that would help me and possibly other Firebase devs discovering this library. I could even fork and try adding documentation myself, unless you're more comfortable doing that instead, especially with #23 and #31 in the works.

Definitely looking forward to using this project in my own and would like to contribute to it in whatever way I can. 😄

Trying to use firestore getting WEBPACK error.

trying to use firestore.

I have auth working great using:

config = { my config }
firebase.initializeApp(config);
const reduxSagaFirebase = new ReduxSagaFirebase(firebase);

When I add firestore to it per the docs:
const reduxSagaFirebase = new ReduxSagaFirebase(firebase, firebase.firestore());

I get.

TypeError: __WEBPACK_IMPORTED_MODULE_0_firebase___default.a.firestore is not a function

Quite a bit of googling has turned up next to nothing. Any ideas?

Thanks

Getting Custom User Data

Hey,

First of all, thanks for such a useful repo!

Sorry if this is a stupid/easy question but I've become really stuck with it...

I am using Firestore and have custom user data saved in a 'Users' Collection. When I use the provided auth channel to get a users auth status, how can I also initiate another channel for syncing their user data from the 'Users' collection?

Immutable Error

Getting 'Immutable Error' in my reducer after calling the createUserWithEmailAndPassword function.
The response seem to return a promise, is there a way to sort this?

My code:

export function * register (action) {
  const { email, password } = action

  // make the call to the api
  try {
    const response = yield call(reduxSagaFirebase.auth.createUserWithEmailAndPassword, email, password)

    yield put(RegisterActions.registerSuccess(response))
  } catch (error) {
    yield put(RegisterActions.registerFailure(error))
  }
}

An in-range update of firebase is breaking the build 🚨

Version 3.7.4 of firebase just got published.

Branch Build failing 🚨
Dependency firebase
Current Version 3.7.3
Type peerDependency

This version is covered by your current version range and after updating it in your project the build failed.

As firebase is “only” a peerDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this 💪


Status Details
  • bitHound - Dependencies No failing dependencies. Details

  • bitHound - Code No failing files. Details

  • ci/circleci Your tests passed on CircleCI! Details

  • semaphoreci The build failed on Semaphore. Details

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

TypeError: Cannot read property 'getCollection' of undefined

Hi there,
Just wanted to checkout your sagas for firestore but I can't seem to get it running
Getting this error:
at rootSaga at takeEvery at getUsers TypeError: Cannot read property 'getCollection' of undefined

code:
function* getUsers() { const snapshot = yield call(rsf.firestore.getCollection, 'users'); let users; snapshot.forEach(user => { users = { ...users, [user.id]: user.data() } }); yield put(listSuccess(users)); }

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.