[英]How To Query Firestore to get Document by String Field (Search Engine Friendly Slug)
I have a Component in React called ShowArticle
and I am trying to query for a single document in Firestore
in my articles
collection by a string field called slug so that I can format my URLs as //myhost.com/article/show/:slug
where slug is the matching, unique string in my Firestore. 我在React中有一个名为
ShowArticle
的组件,我正在尝试通过名为slug的字符串字段在我的articles
集中的Firestore
中查询单个文档,以便可以将URL设置为//myhost.com/article/show/:slug
slug是Firestore中匹配的唯一字符串。
As my Route I have: 作为路线,我有:
<Route exact path="/article/show/:slug" component={ShowArticle} />
So I am getting the :slug
parameter correctly with const { slug } = props.match.params;
所以我用
const { slug } = props.match.params;
正确获取了:slug
参数const { slug } = props.match.params;
inside of ShowArticle
component. 在
ShowArticle
组件内部。
When I query the Firestore for a slug that exists in my database I receive no data back from Firestore. 当我向Firestore查询数据库中存在的块时,我没有收到来自Firestore的数据。
How do I retrieve an Article document by a unique string value for SEF URLs? 如何通过SEF URL的唯一字符串值检索文章文档?
My ShowArticle Component is as follows: 我的ShowArticle组件如下:
import React, { Component } from 'react'; import { connect } from 'react-redux'; import { compose } from 'redux'; import { firestoreConnect } from 'react-redux-firebase'; import { PropTypes } from 'prop-types'; import Article from "./Article"; class ShowArticle extends Component { render() { const { article } = this.props; if (article) { return ( <div> <Article key={article.id} title={article.title} date={article.date} body={article.body} /> </div> ); } else { return ( <div>Loading...</div> ) } } } ShowArticle.propTypes = { firestore: PropTypes.object.isRequired }; export default compose( firestoreConnect(props => { const { slug } = props.match.params; console.log(slug); return [ {collection: 'articles', storeAs: 'article', doc: slug } ] }), connect(({ firestore: { ordered } }, props) => ({ article: ordered.article && ordered.article[0] })) )(ShowArticle);
In the callback to firestoreConnect()
change doc: slug
to queryParams: [ 'equalTo=' + slug ]
在
firestoreConnect()
的回调中,将doc: slug
更改为queryParams: [ 'equalTo=' + slug ]
So you will end up with: 因此,您将得到:
export default compose(
firestoreConnect(props => {
const { slug } = props.match.params;
console.log(slug);
return [
{collection: 'articles', storeAs: 'article', queryParams: [ 'equalTo=' + slug ] }
]
}),
connect(({ firestore: { ordered } }, props) => ({
article: ordered.article && ordered.article[0]
}))
)(ShowArticle);
Reference http://react-redux-firebase.com/docs/queries.html#notParsed in the docs for the react-redux-firebase
package. 请参考文档中有关
react-redux-firebase
软件包的http://react-redux-firebase.com/docs/queries.html#notPars 。
Most probably you are using the latest version of React Router (v4+). 很可能您正在使用最新版本的React Router(v4 +)。 Because in older React Router, it's the way to make available the id with the props.
因为在较旧的React Router中,这是使ID与道具一起可用的方法。 But in newer react-router library, you have to wrap the whole component with the "withRouter" higher-order component.
但是在更新的react-router库中,您必须使用“ withRouter”高阶组件包装整个组件。 It will pass updated match, location, and history props to the wrapped component whenever it renders.
每当渲染时,它将更新的匹配,位置和历史道具传递给包装的组件。
At first, you have to import the withRouter. 首先,您必须导入withRouter。
import { withRouter } from "react-router";
Then you have to wrap it with withRouter. 然后,您必须使用withRouter包装它。
export default withRouter(compose(
firestoreConnect(props => {
const { slug } = props.match.params;
console.log(slug);
return [
{collection: 'articles', storeAs: 'article', doc: slug }
]
}),
connect(({ firestore: { ordered } }, props) => ({
article: ordered.article && ordered.article[0]
}))
)(ShowArticle))
This works for me like a charm! 这对我来说就像一种魅力!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.