Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support for offline data? #9

Open
cworf opened this issue Mar 23, 2018 · 3 comments
Open

support for offline data? #9

cworf opened this issue Mar 23, 2018 · 3 comments

Comments

@cworf
Copy link

cworf commented Mar 23, 2018

firestore documentation gives the following example of how to use there built in persistence function. Though it seems like since im using mobx/firestorter this may need to be implemented in a different way. Is this a feature I can utilize using the firestorter API?

firebase.initializeApp({
  apiKey: '### FIREBASE API KEY ###',
  authDomain: '### FIREBASE AUTH DOMAIN ###',
  projectId: '### CLOUD FIRESTORE PROJECT ID ###',
}
);

firebase.firestore().enablePersistence()
  .then(function() {
      // Initialize Cloud Firestore through firebase
      var db = firebase.firestore();
  })
  .catch(function(err) {
      if (err.code == 'failed-precondition') {
          // Multiple tabs open, persistence can only be enabled
          // in one tab at a a time.
          // ...
      } else if (err.code == 'unimplemented') {
          // The current browser does not support all of the
          // features required to enable persistence
          // ...
      }
  });
@IjzerenHein
Copy link
Owner

Hey Colin, it's great than you mention this. This is an important feature to me, and I hope to get some time to implement/investigate this on short notice.

My initial thought is to allow initialisation of Firestorter with a promise that resolves to the firestore app object. And then it would work sort of like this:

async function init() {
  try {
    await firebase.firestore().enablePersistence();
  }
  catch (err) {
    if (err.code == 'failed-precondition') {
      console.warn('Multiple tabs open, persistence can only be enabled in one tab at a time.');
    } else if (err.code == 'unimplemented') {
      console.warn('The current browser does not support all of the features required to enable persistence');
    }
  }
  initFirestorter({firebase: firebase});
};
init();

@IjzerenHein
Copy link
Owner

Hi, regarding offline persistence, I suggest the following approach which I've been using successfully in my application for some time now. It deals with the problem in 3 phases:

  1. Render the application after initialisation has occurred
  2. Use a mobx-react Provider to create a Store and add it as a context
  3. Wrap your components with a HOC that passes in the store as a prop

1. Render the application after initialisation has occurred

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import firebase from '@firebase/app';
import '@firebase/firestore';
import { initFirestorter } from 'firestorter';
import App from './App';

firebase.initializeApp({...);

async function initFirestore() {
  firebase.firestore().settings({ timestampsInSnapshots: true });

  try {
    await firebase.firestore().enablePersistence();
  } catch (err) {
    console.error('Failed to enable firebase persistency: ', err.message);
  }

  initFirestorter({ firebase: firebase });
}

initFirestore().then(() => {
  ReactDOM.render(<App>, document.getElementById('root'));
});

2. Use a mobx-react Provider to create a Store and add it as a context

App.js

import React from 'react';
import StoreProvider from './StoreProvider';

const App = () => (
  <StoreProvider>
    <Todos />
  </StoreProvider>
);
export default App;

StoreProvider

import React, { Component } from 'react';
import { Provider } from 'mobx-react';
import Store from './Store';

export default class StoreProvider extends Component {
  state = {
    store: new Store(),
  };

  render() {
    return <Provider store={this.state.store}>{this.props.children}</Provider>;
  }
}

Store.js

import { Collection } from 'firestorter';

export default class Store {
  constructor() {
    this.todos = new Collection('todos');
    ...
  }
}

3. Wrap your components with a HOC that passes in the store as a prop

Todos.js

import React, { Component } from 'react';
import storeObserver from './storeObserver';

class Todos extends Component{
  render() {
    const { store } = this.props;
    const { todos } = store;
    return (
      <div>
        {todos.docs.map(todo => <Todo doc={todo} />)}
      </div>
    );
  }
}

// Wrap the component in a HOC which passes in the store
export default storeObserver(Todos);

storeObserver.js

import { inject, observer } from 'mobx-react';

function storeObserver(WrappedComponent) {
  return inject('store')(observer(WrappedComponent));
}

export default storeObserver;

@cgadam
Copy link
Contributor

cgadam commented Oct 22, 2020

It seems like we're still unable to add a new document to a collection while being offline. (and let the collection decide what its auto id should look like) We can't do what is suggested here: firebase/firebase-js-sdk#2030 (comment) with the current's Collection API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants