UNPKG

react-firestore

Version:

React components to fetch data from firestore using render props

364 lines (293 loc) 9.75 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var React = require('preact'); var React__default = _interopDefault(React); var _inheritsLoose = _interopDefault(require('@babel/runtime/helpers/inheritsLoose')); var _extends = _interopDefault(require('@babel/runtime/helpers/extends')); var _objectWithoutPropertiesLoose = _interopDefault(require('@babel/runtime/helpers/objectWithoutPropertiesLoose')); var hoistStatics = _interopDefault(require('hoist-non-react-statics')); var FirestoreCache = function () {}; var FirestoreContext = React__default.createContext(null); var FirestoreProvider = /*#__PURE__*/ function (_Component) { _inheritsLoose(FirestoreProvider, _Component); function FirestoreProvider(props) { var _this = _Component.call(this, props) || this; var firebase = props.firebase, useTimestampsInSnapshots = props.useTimestampsInSnapshots; var firestore = firebase.firestore(); if (typeof useTimestampsInSnapshots !== 'undefined') { firestore.settings({ timestampsInSnapshots: useTimestampsInSnapshots }); } _this.state = { firestoreDatabase: firestore, firestoreCache: new FirestoreCache() }; return _this; } var _proto = FirestoreProvider.prototype; _proto.render = function render() { return React__default.h(FirestoreContext.Provider, { value: this.state }, this.props.children); }; return FirestoreProvider; }(React.Component); FirestoreProvider.defaultProps = {}; var Firestore = function (_ref) { var render = _ref.render; return React__default.h(FirestoreContext.Consumer, null, function (_ref2) { var firestoreDatabase = _ref2.firestoreDatabase; return render({ firestore: firestoreDatabase }); }); }; var withFirestore = function (Component) { var C = function (_ref) { var wrappedComponentRef = _ref.wrappedComponentRef, remainingProps = _objectWithoutPropertiesLoose(_ref, ["wrappedComponentRef"]); return React__default.h(FirestoreContext.Consumer, null, function (value) { if (!value) { throw new Error('FirestoreProvider is missing'); } var firestoreDatabase = value.firestoreDatabase; return React__default.h(Component, _extends({}, remainingProps, { firestore: firestoreDatabase, ref: wrappedComponentRef })); }); }; C.displayName = "withFirestore(" + (Component.displayName || Component.name) + ")"; C.WrappedComponent = Component; return hoistStatics(C, Component); }; /** * Deep equality comparison for Arrays * @param {Array} a The array to compare against * @param {Array} b The array to compare with * @returns {boolean} If the two arrays are equal */ function deepEqual(a, b) { if (Array.isArray(a) && Array.isArray(b)) { if (a.length !== b.length) { return false; } for (var i = 0; i < a.length; i++) { if (!deepEqual(a[i], b[i])) { return false; } } return true; } else { return a === b; } } var FirestoreCollection = /*#__PURE__*/ function (_Component) { _inheritsLoose(FirestoreCollection, _Component); function FirestoreCollection() { var _this; for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _Component.call.apply(_Component, [this].concat(args)) || this; _this.state = { isLoading: true, data: [], error: null, snapshot: null }; _this.setupFirestoreListener = function () { var _this$props = _this.props, firestore = _this$props.firestore, path = _this$props.path, queryProps = _objectWithoutPropertiesLoose(_this$props, ["firestore", "path"]); var collectionRef = firestore.collection(path); var query = _this.buildQuery(collectionRef, queryProps); _this.unsubscribe = query.onSnapshot(_this.handleOnSnapshotSuccess, _this.handleOnSnapshotError); }; _this.handleOnSnapshotSuccess = function (snapshot) { if (snapshot) { _this.setState({ isLoading: false, data: snapshot.docs.map(function (doc) { return _extends({ id: doc.id }, doc.data()); }), error: null, snapshot: snapshot }); } }; _this.handleOnSnapshotError = function (error) { _this.setState({ isLoading: false, data: [], error: error, snapshot: null }); }; _this.buildQuery = function (collectionRef, queryProps) { var sort = queryProps.sort, limit = queryProps.limit, filter = queryProps.filter; var query = collectionRef; if (sort) { sort.split(',').forEach(function (sortItem) { var _sortItem$split = sortItem.split(':'), field = _sortItem$split[0], order = _sortItem$split[1]; query = query.orderBy(field, order); }); } if (limit) { query = query.limit(limit); } if (filter) { //if filter is array of array, build the compound query if (Array.isArray(filter[0])) { filter.forEach(function (clause) { var _query; query = (_query = query).where.apply(_query, clause); }); } else { var _query2; //build the simple query query = (_query2 = query).where.apply(_query2, filter); } } return query; }; return _this; } var _proto = FirestoreCollection.prototype; _proto.componentDidMount = function componentDidMount() { this.setupFirestoreListener(); }; _proto.componentWillUnmount = function componentWillUnmount() { this.handleUnsubscribe(); }; _proto.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { var _this2 = this; if (nextProps.path !== this.props.path || nextProps.sort !== this.props.sort || nextProps.limit !== this.props.limit || !deepEqual(nextProps.filter, this.props.filter)) { this.handleUnsubscribe(); this.setState({ isLoading: true }, function () { return _this2.setupFirestoreListener(); }); } }; _proto.handleUnsubscribe = function handleUnsubscribe() { if (this.unsubscribe) { this.unsubscribe(); } }; _proto.render = function () { var _this$props2 = this.props, children = _this$props2.children, render = _this$props2.render; if (render) return render(this.state); if (typeof children === 'function') return children(this.state); return null; }; return FirestoreCollection; }(React.Component); var FirestoreCollection$1 = withFirestore(FirestoreCollection); var FirestoreDocument = /*#__PURE__*/ function (_Component) { _inheritsLoose(FirestoreDocument, _Component); function FirestoreDocument() { var _this; for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _Component.call.apply(_Component, [this].concat(args)) || this; _this.state = { isLoading: true, data: null, error: null, snapshot: null }; _this.setupFirestoreListener = function () { var _this$props = _this.props, firestore = _this$props.firestore, path = _this$props.path; var documentRef = firestore.doc(path); _this.unsubscribe = documentRef.onSnapshot(_this.handleOnSnapshotSuccess, _this.handleOnSnapshotError); }; _this.handleOnSnapshotError = function (error) { _this.setState({ isLoading: false, error: error, data: null, snapshot: null }); }; _this.handleOnSnapshotSuccess = function (snapshot) { if (snapshot) { var newState = { isLoading: false, error: null, snapshot: snapshot }; try { var documentData = snapshot.data(); newState.data = _extends({ id: snapshot.id }, documentData); } catch (error) { newState.error = error; } _this.setState(newState); } }; return _this; } var _proto = FirestoreDocument.prototype; _proto.componentDidMount = function componentDidMount() { this.setupFirestoreListener(); }; _proto.componentWillUnmount = function componentWillUnmount() { this.handleUnsubscribe(); }; _proto.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { var _this2 = this; if (nextProps.path !== this.props.path) { this.handleUnsubscribe(); this.setState({ isLoading: true }, function () { return _this2.setupFirestoreListener(); }); } }; _proto.handleUnsubscribe = function handleUnsubscribe() { if (this.unsubscribe) { this.unsubscribe(); } }; _proto.render = function () { var _this$props2 = this.props, children = _this$props2.children, render = _this$props2.render; if (render) return render(this.state); if (typeof children === 'function') return children(this.state); return null; }; return FirestoreDocument; }(React.Component); var FirestoreDocument$1 = withFirestore(FirestoreDocument); exports.Firestore = Firestore; exports.FirestoreProvider = FirestoreProvider; exports.FirestoreCollection = FirestoreCollection$1; exports.FirestoreDocument = FirestoreDocument$1; exports.withFirestore = withFirestore;