gpt4 book ai didi

reactjs - 您如何在 Firestore 中获取与 authUser 相关的用户数据库详细信息?

转载 作者:行者123 更新时间:2023-12-03 13:20:35 24 4
gpt4 key购买 nike

我想弄清楚如何获取用户名,该用户名是存储在用户集合中的属性,该属性已与 firebase 身份验证模型创建的属性合并。

我可以访问 authUser - 这为我提供了 firebase 在身份验证工具中收集的有限字段,然后我试图从那里访问相关的用户集合(使用相同的 uid)。

我有一个 react 上下文消费者:

import React from 'react';
const AuthUserContext = React.createContext(null);
export default AuthUserContext;

然后在我的组件中,我尝试使用:
const Test = () => (

<AuthUserContext.Consumer>
{authUser => (

<div>
{authUser.email} // I can access the attributes in the authentication collection
{authUser.uid.user.name} //i cannot find a way to get the details in the related user collection document - where the uid on the collection is the same as the uid on the authentication table


</div>
)}
</AuthUserContext.Consumer>
);

const condition = authUser => !!authUser;
export default compose(
withEmailVerification,
withAuthorization(condition),
)(Test);

在我的 firebase.js 中 - 我想我已经尝试将身份验证模型中的 authUser 属性与用户集合属性合并,如下所示:
class Firebase {
constructor() {
app.initializeApp(config).firestore();
/* helpers */
this.fieldValue = app.firestore.FieldValue;


/* Firebase APIs */
this.auth = app.auth();
this.db = app.firestore();

onAuthUserListener = (next, fallback) =>
this.auth.onAuthStateChanged(authUser => {
if (authUser) {
this.user(authUser.uid)
.get()
.then(snapshot => {
const dbUser = snapshot.data();
// default empty roles
if (!dbUser.roles) {
dbUser.roles = {};
}
// merge auth and db user
authUser = {
uid: authUser.uid,
email: authUser.email,
emailVerified: authUser.emailVerified,
providerData: authUser.providerData,
...dbUser,
};
next(authUser);
});
} else {
fallback();
}
});

我找不到从 authUser(它可以让我进入 Authentication 属性)获取的方法 - 到具有与 Authentication 集合中相同 uid 的 id 的用户集合。

我见过 this post ,这似乎有同样的问题,并试图找出答案应该暗示什么 - 但我似乎无法找到一种方法可以从身份验证集合到用户集合,我没有如果合并不能让我访问来自 authUser 的用户集合上的属性,请知道合并对我做了什么。

我试图在我的 firebase.js 中使用一个助手从 uid 给我一个用户 - 但这似乎也没有帮助。
user = uid => this.db.doc(`users/${uid}`);
users = () => this.db.collection('users');

下次尝试

为了添加更多背景,我制作了一个可以记录(但不能渲染)authUser 的测试组件,如下所示:
import React, { Component } from 'react';
import { withFirebase } from '../Firebase/Index';
import { Button, Layout } from 'antd';

import { AuthUserContext, withAuthorization, withEmailVerification } from '../Session/Index';


class Test extends Component {
constructor(props) {
super(props);

this.state = {
loading: false,
user: null,
...props.location.state,
};
}

componentDidMount() {
if (this.state.user) {
return;
}

this.setState({ loading: true });

// this.unsubscribe = this.props.firebase
// .user(authUser.uid)
// .onSnapshot(snapshot => {
// const userData = snapshot.data();
// console.log(userData);
// this.setState({
// user: snapshot.data(),
// loading: false,
// });
// });
}

componentWillUnmount() {
this.unsubscribe && this.unsubscribe();
}



render() {
const { user, loading } = this.state;


return (
<div>
<AuthUserContext.Consumer>
{authUser => (
console.log(authUser),
<p>
</p>


)}
</AuthUserContext.Consumer>

</div>

);

};
}
export default Test;

日志在日志中显示了 uid、电子邮件等的详细信息,但它位于一长串项目中 - 其中许多以 1 或 2 个字母开头(我找不到关键字来找出每个前缀字母的意思)。示例提取如下:

enter image description here

更新此评论:

之前,我说:
uid、email 等字段似乎没有嵌套在这些前缀下,但如果我尝试:
 console.log(authUser.email)

,我收到一条错误消息:

TypeError: Cannot read property 'email' of null



更新:
我刚刚意识到在控制台日志中,我必须展开一个标有以下标签的下拉菜单:

Q {I: Array(0), l:

查看电子邮件属性。有谁知道这个胡言乱语暗指什么?我找不到 key 来弄清楚 Q、I 或 l 的含义,以了解我是否应该引用这些内容来获取身份验证表中的相关属性。也许如果我能弄清楚 - 我可以找到一种使用身份验证集合中的 uid 访问用户集合的方法。

有没有人在前端使用过 React,通过上下文消费者来找出当前用户是谁?如果是这样,您如何访问它们在 Authentication 模型上的属性以及如何访问相关 User 集合上的属性(其中 User 文档上的 docId 是 Authentication 表中的 uid)?

下一次尝试

下一次尝试产生了非常奇怪的结果。

我有 2 个单独的页面,它们是上下文消费者。它们之间的区别在于一个是函数,另一个是类组件。

在函数组件中,我可以渲染 {authUser.email}。当我尝试在类组件中做同样的事情时,我收到一条错误消息:

TypeError: Cannot read property 'email' of null



此错误来自具有相同登录用户的同一 session 。

注意:虽然 firebase 文档说 currentUser 属性在 auth 上可用 - 我根本无法让它工作。

我的功能组件有:
import React from 'react';
import { Link } from 'react-router-dom';
import { compose } from 'recompose';
import { AuthUserContext, withAuthorization, withEmailVerification } from '../Session/Index';


const Account = () => (

<AuthUserContext.Consumer>
{authUser => (
<div>
{authUser.email}
</div>
)}
</AuthUserContext.Consumer>
);

// const condition = authUser => !!authUser;
// export default compose(
// withEmailVerification,
// withAuthorization(condition),
// )(Account);
export default Account;

虽然我无法获得用户文档上的 docId 与经过身份验证的用户的 uid 相同的用户集合属性,但从该组件中,我可以为该用户输出身份验证集合上的电子邮件属性。

Firebase documentation在这里提供了管理用户和访问属性的建议,我还没有找到在 react 中实现这种方法的方法。通过在我的 firebase.js 中创建助手和尝试在组件中从头开始尝试这样做的每一种变化都会在访问 firebase 时产生错误。但是,我可以生成用户列表及其相关的用户集合信息(我无法根据 authUser 的身份获取用户)。

我的类组件有:
import React from 'react';
import {
BrowserRouter as Router,
Route,
Link,
Switch,

} from 'react-router-dom';
import * as ROUTES from '../../constants/Routes';
import { compose } from 'recompose';
import { withFirebase } from '../Firebase/Index';
import { AuthUserContext, withAuthorization, withEmailVerification } from '../Session/Index';



class Dashboard extends React.Component {
state = {
collapsed: false,
};

onCollapse = collapsed => {
console.log(collapsed);
this.setState({ collapsed });
};

render() {
const { loading } = this.state;
// const dbUser = this.props.firebase.app.snapshot.data();
// const user = Firebase.auth().currentUser;
return (
<AuthUserContext.Consumer>
{authUser => (

<div>
{authUser.email} // error message as shown above
{console.log(authUser)} // output logged in amongst a long list of menus prefixed with either 1 or 2 characters. I can't find a key to decipher what these menus mean or do.
</div>
)}
</AuthUserContext.Consumer>
);
}
}

//export default withFirebase(Dashboard);
export default Dashboard;

在我的 AuthContext.Provider - 我有:
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 });
},
);
}

componentWillUnmount() {
this.listener();
};

render() {
return (
<AuthUserContext.Provider value={this.state.authUser}>
<Component {...this.props} />
</AuthUserContext.Provider>
);
}
}
return withFirebase(WithAuthentication);

};
export default withAuthentication;

下一次尝试

很奇怪,通过这次尝试,我试图控制台记录我可以看到数据库中存在的值,并且 name 的值被返回为“未定义”,其中数据库中有一个字符串。

这个尝试有:
    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 { withFirebase } from '../Firebase/Index';
import { AuthUserContext, withAuthorization, withEmailVerification } from '../Session/Index';



class Dash extends React.Component {
// state = {
// collapsed: 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)
// .user(this.props.user.uid)
// .user(authUser.uid)
// .user(authUser.id)
// .user(Firebase.auth().currentUser.id)
// .user(Firebase.auth().currentUser.uid)

.onSnapshot(snapshot => {
this.setState({
user: snapshot.data(),
loading: false,
});
});
}

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 (
<AuthUserContext.Consumer>
{authUser => (

<div>
{loading && <div>Loading ...</div>}

<Layout style={{ minHeight: '100vh' }}>
<Sider collapsible collapsed={this.state.collapsed} onCollapse={this.onCollapse}>
<div />

</Sider>
<Layout>

<Header>
{console.log("authUser:", authUser)}
// this log returns the big long list of outputs - the screen shot posted above is an extract. It includes the correct Authentication table (collection) attributes
{console.log("authUser uid:", authUser.uid)}
// this log returns the correct uid of the current logged in user
{console.log("Current User:", this.props.firebase.auth.currentUser.uid)}
// this log returns the correct uid of the current logged in user
{console.log("current user:", this.props.firebase.db.collection("users").doc(this.props.firebase.auth.currentUser.uid
))}
// this log returns a big long list of things under a heading: DocumentReference {_key: DocumentKey, firestore: Firestore, _firestoreClient: FirestoreClient}. One of the attributes is: id: (...) (I can't click to expand this).
{console.log("current user:", this.props.firebase.db.collection("users").doc(this.props.firebase.auth.currentUser.uid
).name)}
//this log returns: undefined. There is an attribute in my user document called 'name'. It has a string value on the document with the id which is the same as the currentUser.uid.
<Text style={{ float: 'right', color: "#fff"}}>

{user && (
<Text style={{ color: "#fff"}}>{user.name}
//this just gets skipped over in the output. No error but also does not return the name.
</Text>


)}

</Text>
</Header>
</Layout>
</Layout>

</div>
)}
</AuthUserContext.Consumer>
);
}
}

export default withFirebase(Dash);

下一次尝试

因此,这种尝试很笨拙,并且没有使用我在上面尝试使用的帮助程序或快照查询,而是将用户集合文档属性记录到控制台,如下所示:

{
this.props.firebase.db.collection('users').doc(authUser.uid).get()
      .then(doc => {
console.log(doc.data().name)
})

}

我不能做的是找到一种在 jsx 中呈现该名称的方法

你实际上如何打印输出?

当我尝试:
{ 


this.props.firebase.db.collection('users').doc(authUser.uid).get().data().name

}

我收到一条错误消息:

TypeError: this.props.firebase.db.collection(...).doc(...).get(...).data is not a function



当我尝试:
{ 



this.props.firebase.db.collection('users').doc(authUser.uid).get()
.then(doc => {
console.log(doc.data().name),
<p>doc.data().name</p>
})
}

我收到一条错误消息:

Line 281:23: Expected an assignment or function call and instead saw an expression no-unused-expressions



当我尝试:
{ 


this.props.firebase.db.collection('users').doc(authUser.uid).get("name")
.then(doc => {
console.log(doc.data().name),
<p>doc.data().name</p>
})
}

错误消息说:

Expected an assignment or function call and instead saw an expression



我准备放弃尝试找出如何使快照查询工作的尝试 - 如果我可以获取要在屏幕上呈现的用户集合的名称。任何人都可以帮助完成这一步吗?

下一次尝试

我找到了 this post .它对需要发生的事情有一个很好的解释,但我无法实现它,因为 componentDidMount 不知道 authUser 是什么。

我目前的尝试如下 - 但是,正如目前所写,authUser 是返回值的包装器 - 而 componentDidMount 段不知道 authUser 是什么。
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 } from '../Session/Index';




const { Title, Text } = 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.props.firebase.db
.collection('users')
.doc(authUser.uid)
.get()
.then(doc => {
this.setState({ user_name: doc.data().name });
// loading: false,
});
}

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 (
<AuthUserContext.Consumer>
{ authUser => (

<div>

<Header>

{/*
{
this.props.firebase.db.collection('users').doc(authUser.uid).get()
.then(doc => {
console.log( doc.data().name
)
})
}
*/}


</Text>
</Header>

<Switch>

</Switch>

</div>
)}
</AuthUserContext.Consumer>
);
}
}

export default withFirebase(Dashboard);

下一次尝试

接下来,我尝试将仪表板的路由包装在 AuthContext.Consumer 中,以便整个组件可以使用它 - 从而让我在 componentDidMount 函数中访问登录用户。

我把路线改为:
<Route path={ROUTES.DASHBOARD} render={props => (
<AuthUserContext.Consumer>
{ authUser => (
<Dashboard authUser={authUser} {...props} />
)}
</AuthUserContext.Consumer>
)} />

并从仪表板组件渲染语句中删除了使用者。

然后在 Dashboard 组件上的 componentDidMount 中,我尝试了:
componentDidMount() {
if (this.state.user) {
return;
}

this.setState({ loading: true });

this.unsubscribe =
this.props.firebase.db
.collection('users')
//.doc(this.props.firebase.db.collection('users').doc(this.props.firebase.authUser.uid))
.doc(this.props.firebase.db.collection('users').doc(this.props.authUser.uid))
.get()
.then(doc => {
this.setState({ name: doc.data().name });
loading: false,
});
}

当我尝试这个时,我收到一条错误消息:

FirebaseError: Function CollectionReference.doc() requires its first argument to be of type non-empty string, but it was: a custom DocumentReference object



下一次尝试
下面的人似乎在第一个提出的解决方案中找到了一些有用的东西。我没能在其中找到任何有用的东西,但是通过它的建议重新阅读,我正在努力了解 firebase 文档中的示例(它没有透露如何为 .doc() 请求提供 :uid 值),具体如下:
db.collection("cities").doc("SF");

docRef.get().then(function(doc) {
if (doc.exists) {
console.log("Document data:", doc.data());
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}

与我在 componentDidMount 函数中的尝试完全不同,后者是:
this.unsubscribe =
this.props.firebase.db
.collection('users')
// .doc(this.props.firebase.db.collection('users').doc(this.props.firebase.authUser.uid))
// .doc(this.props.firebase.db.collection('users').uid: this.props.firebase.auth().currentUser.uid )
.doc(this.props.authUser.uid)
.get()
.then(doc => {
this.setState({ user.name: doc.data().name });
// loading: false,
}else {
// doc.data() will be undefined in this case
console.log("Can't find this record");
}

);
}

也许解决这一步是一个线索,将有助于插入这一结果。谁能找到任何更好的 firestore 文档来展示如何使用登录的用户监听器 uid 获取用户收集记录?

为此,我可以从 FriendlyEats 代码实验室 example 中看到, 尝试将 doc.id 赋予代码中的 id 搜索值。我不知道这段代码是用什么语言编写的——但它看起来与我试图做的很相似——我只是不知道如何从那个例子转向我知道如何使用的东西。
display: function(doc) {
var data = doc.data();
data['.id'] = doc.id;
data['go_to_restaurant'] = function() {
that.router.navigate('/restaurants/' + doc.id);
};

最佳答案

我从您问题的最后一行( users = () => this.db.collection('users'); )了解到,您存储用户额外信息的集合称为 users并且此集合中的用户文档使用 userId (uid) 作为 docId。

以下应该可以解决问题(未经测试):

class Firebase {
constructor() {
app.initializeApp(config).firestore();
/* helpers */
this.fieldValue = app.firestore.FieldValue;


/* Firebase APIs */
this.auth = app.auth();
this.db = app.firestore();

onAuthUserListener = (next, fallback) =>
this.auth.onAuthStateChanged(authUser => {
if (authUser) {
this.db.collection('users').doc(authUser.uid)
.get()
.then(snapshot => {
const userData = snapshot.data();
console.log(userData);
//Do whatever you need with userData
//i.e. merging it with authUser
//......

next(authUser);
});
} else {
fallback();
}
});

因此,在观察者集内通过 onAuthStateChanged()方法,当我们检测到用户已登录(即在 if (authUser) {} 中)时,我们使用其 uidusers中查询该用户对应的唯一文档集合(参见 read one document get() 方法的文档)。

关于reactjs - 您如何在 Firestore 中获取与 authUser 相关的用户数据库详细信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59657511/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com