Я пытаюсь выяснить, как запросить запись в firestore, используя идентификатор пользователя authUser в качестве идентификатора документа.
Я видел этот пост и пытаюсь реализовать логи c путем обновления состояния пользователя, чтобы функция componentDidMount могла найти документ в коллекции пользователей в firestore, где этот документ имеет идентификатор, совпадающий с authUser.uid в коллекции Authentication.
У меня есть authListener с:
import React from 'react';
import { AuthUserContext } from '../Session/Index';
import { withFirebase } from '../Firebase/Index';
const withAuthentication = Component => {
class WithAuthentication extends React.Component {
constructor(props) {
super(props);
this.state = {
authUser: null,
};
}
componentDidMount() {
this.listener = this.props.firebase.auth.onAuthStateChanged(
authUser => {
authUser
? this.setState({ authUser })
: this.setState({ authUser: null });
},
);
}
// componentDidMount() {
// this.listener = this.props.firebase.onAuthUserListener(
// /* next() */ (authUserWithData) => this.setState({authUser: authUserWithData}),
// /* fallback() */ () => this.setState({authUser: null})
// );
// }
componentWillUnmount() {
this.listener();
};
render() {
return (
<AuthUserContext.Provider value={this.state.authUser}>
<Component {...this.props} />
</AuthUserContext.Provider>
);
}
}
return withFirebase(WithAuthentication);
};
export default withAuthentication;
Мой конфигурационный файл firebase определяет помощника с:
onAuthUserListener(next, fallback) {
// onUserDataListener(next, fallback) {
return this.auth.onAuthStateChanged(authUser => {
if (!authUser) {
// user not logged in, call fallback handler
fallback();
return;
}
this.user(authUser.uid).get()
.then(snapshot => {
let snapshotData = snapshot.data();
let userData = {
...snapshotData, // snapshotData first so it doesn't override information from authUser object
uid: authUser.uid,
email: authUser.email,
emailVerified: authUser.emailVerifed,
providerData: authUser.providerData
};
setTimeout(() => next(userData), 0); // escapes this Promise's error handler
})
.catch(err => {
// TODO: Handle error?
console.error('An error occured -> ', err.code ? err.code + ': ' + err.message : (err.message || err));
setTimeout(fallback, 0); // escapes this Promise's error handler
});
});
}
Затем в компоненте, где я пытаюсь использовать вошедшего в систему Атрибуты пользователя из связанной коллекции пользователей в облачном хранилище. У меня есть компонент с:
import React from 'react';
import {
BrowserRouter as Router,
Route,
Link,
Switch,
useRouteMatch,
} from 'react-router-dom';
import * as ROUTES from '../../constants/Routes';
import { compose } from 'recompose';
import { Divider, Layout, Card, Tabs, Typography, Menu, Breadcrumb, Icon } from 'antd';
import { withFirebase } from '../Firebase/Index';
import { AuthUserContext, withAuthorization, withEmailVerification, withAuthentication } from '../Session/Index';
const { Title, Text, Paragraph } = Typography
const { TabPane } = Tabs;
const { Header, Content, Footer, Sider } = Layout;
const { SubMenu } = Menu;
class Dashboard extends React.Component {
// state = {
// collapsed: false,
// loading: false,
// };
constructor(props) {
super(props);
this.state = {
collapsed: false,
loading: false,
user: null,
...props.location.state,
};
}
componentDidMount() {
if (this.state.user) {
return;
}
this.setState({ loading: true });
// this.unsubscribe =
// this.props.firebase
// .user(this.props.match.params.id)
// .onSnapshot(snapshot => {
// this.setState({
// user: snapshot.data(),
// loading: false,
// });
// });
// }
// firebase.firestore().collection("users")
// .doc(this.state.uid)
// .get()
// .then(doc => {
// this.setState({ post_user_name: doc.data().name });
// });
// }
// - this is the current attempt -
this.unsubscribe =
this.props.firebase.db
.collection('users')
.doc(this.props.authUser.uid)
.get()
.then(doc => {
this.setState({ name: doc.data().name });
// loading: false,
}
// else {
// // doc.data() will be undefined in this case
// console.log("Can't find this record");
// }
);
}
componentWillUnmount() {
this.unsubscribe && this.unsubscribe();
}
onCollapse = collapsed => {
console.log(collapsed);
this.setState({ collapsed });
};
render() {
// const { loading } = this.state;
// const { user, loading } = this.state;
// let match = useRouteMatch();
// const dbUser = this.props.firebase.app.snapshot.data();
// const user = Firebase.auth().currentUser;
return (
<div>
<Header>
<Text style={{ float: 'right', color: "#fff"}}>{this.state.authUser.uid}
{/*
{this.props.firebase.db.collection('users').doc(authUser.uid).get()
.then(doc => {
console.log(doc.data().name)
})
}
{
this.props.firebase.db.collection('users').doc(this.props.authUser.uid).get()
.then(doc => {
console.log("test", doc.data().name
)
})
}
{console.log(this.props.user.email)}
*/}
</div>
);
}
}
Когда я пытаюсь использовать authUser.uid в запросе componentDidMount, я получаю сообщение об ошибке:
FirebaseError: Функция CollectionReference.do c () требует, чтобы ее первый аргумент имел тип непустую строку, но это было: пользовательский объект DocumentReference obj ect
Маршрут для этого компонента находится в контексте authUser Context.Consumer:
<Route path={ROUTES.DASHBOARD} render={props => (
<AuthUserContext.Consumer>
{ authUser => (
<Dashboard authUser={authUser} {...props} />
)}
</AuthUserContext.Consumer>
)} />
Я могу console.log атрибуты, хранящиеся в коллекции пользователей, с помощью do c id, который является идентификатором authUser в коллекции Authentication, но я не могу найти способ поместить этот идентификатор authUser в запрос firebase к коллекции пользователей в функции componentDidMount.
Я видел этот пост , который предполагает, что значение do c () может быть чем-то отличным от строки, но что это может быть проблемой синхронизации в этой базе данных, возможно, не идентифицировал authUser по точке, в которой выполняется запрос. Если это правда, где я могу поставить тег await в запросе, чтобы решить эту проблему?
Я также видел этот пост , который говорит о том, что мне нужно построить обходной путь для преобразования authUser.uid в строку, прежде чем я передам ее в запрос firestore. Некоторые из этих ответов express интересуются знанием, может ли идентификатор do c отличаться от строки.