मैं यह पता लगाने की कोशिश कर रहा हूं कि उपयोगकर्ता नाम कैसे प्राप्त किया जाए जो एक उपयोगकर्ता संग्रह में संग्रहीत विशेषता है, जिसे फायरबेस प्रमाणीकरण मॉडल द्वारा बनाई गई विशेषताओं के साथ मिला दिया गया है।
मैं तक पहुँच सकता है - जो मुझे सीमित उपकरण देता है फायरबस प्रमाणीकरण उपकरण में एकत्र करता है, और फिर मैं वहां से संबंधित उपयोगकर्ता संग्रह (जो उसी यूआईडी का उपयोग करता है) को प्राप्त करने की कोशिश कर रहा हूं।
मेरे पास एक प्रतिक्रिया संदर्भ उपभोक्ता है:
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 में - मुझे लगता है कि मैंने ऑथेंटिकेशन मॉडल से ऑस्ट्रियन मॉडल के ऑरिजनल गुण को मर्ज करने की कोशिश की है।
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();
}
});
मुझे उपयोगकर्ता संग्रह से प्राप्त करने का एक तरीका नहीं मिल सकता है (जो मुझे प्रमाणीकरण विशेषताओं पर ले जाने के लिए काम करता है) - उपयोगकर्ता संग्रह के लिए जो प्रमाणीकरण संग्रह से समान यूआईडी के साथ एक आईडी है।
मैंने इस पोस्ट को देखा है , जिसमें एक ही समस्या है और यह पता लगाने की कोशिश की गई है कि उत्तर क्या माना जाता है - लेकिन मुझे ऐसा तरीका नहीं मिल रहा है जो प्रमाणीकरण संग्रह से उपयोगकर्ता संग्रह तक पहुंचने के लिए काम करता हो और मुझे नहीं पता कि मेरे लिए क्या मर्ज है अगर यह मुझे उपयोगकर्ता संग्रह पर विशेषताओं का उपयोग करने की अनुमति नहीं दे रहा है।
मैंने अपने फायरबेस में एक सहायक का उपयोग करने की कोशिश की। मुझे एक यूआईडी से एक उपयोगकर्ता देने के लिए - लेकिन वह भी मदद नहीं करता है।
user = uid => this.db.doc(`users/${uid}`);
users = () => this.db.collection('users');
अगला प्रयास
अधिक बैकग्राउंड जोड़ने के लिए, मैंने एक टेस्ट कंपोनेंट बनाया है जो लॉगऑन कर सकता है (लेकिन रेंडर नहीं)
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;
लॉग लॉग में यूआईडी, ईमेल आदि के लिए विवरण दिखाता है, लेकिन यह मदों की एक लंबी सूची के बीच है - जिनमें से कई 1 या 2 अक्षरों के साथ पूर्वनिर्मित हैं (मुझे पता लगाने के लिए एक कुंजी नहीं मिल सकती है कि इनमें से प्रत्येक उपसर्ग क्या है अक्षर का मतलब है)। नीचे दिया गया उदाहरण:
इस टिप्पणी पर अद्यतन:
इससे पहले, मैंने कहा: यूआईडी, ईमेल आदि के लिए फ़ील्ड इन उपसर्गों के नीचे नेस्टेड प्रतीत नहीं होते हैं, लेकिन अगर मैं इसके लिए प्रयास करता हूं:
console.log(authUser.email)
, मुझे एक त्रुटि मिलती है जो कहती है:
TypeError: null की प्रॉपर्टी 'ईमेल' नहीं पढ़ सकता
अद्यतन: मुझे बस एहसास हुआ कि कंसोल लॉग में, मुझे एक ड्रॉप डाउन मेनू का विस्तार करना होगा जो लेबल है:
क्यू {I: एरे (0), एल:
ईमेल विशेषता देखने के लिए। क्या किसी को पता है कि इस जिबरिश का क्या मतलब है? मुझे यह पता करने के लिए कि Q, I या l का क्या मतलब है, यह जानने के लिए कि क्या मैं इन चीजों को संदर्भित करने वाला हूं, प्रमाणीकरण तालिका में प्रासंगिक विशेषताओं को प्राप्त करने के लिए एक कुंजी नहीं मिल सकती है। शायद अगर मैं यह पता लगा सकता हूं - मैं प्रमाणीकरण संग्रह से यूआईडी का उपयोग करके उपयोगकर्ता संग्रह के लिए एक रास्ता खोज सकता हूं।
क्या किसी ने उपभोक्ता के संदर्भ के साथ सामने के छोर पर प्रतिक्रिया का उपयोग किया है, यह पता लगाने के लिए कि वर्तमान उपयोगकर्ता कौन है? यदि हां, तो आप प्रमाणीकरण मॉडल पर उनकी विशेषताओं का उपयोग कैसे करते हैं और आपने संबंधित उपयोगकर्ता संग्रह पर विशेषताओं का उपयोग कैसे किया (जहां उपयोगकर्ता दस्तावेज़ पर docId प्रमाणीकरण तालिका से यूआईडी है)?
अगले ATTEMPT
अगले प्रयास ने एक बहुत ही अजीब परिणाम उत्पन्न किया है।
मेरे पास 2 अलग-अलग पृष्ठ हैं जो संदर्भ उपभोक्ता हैं। उनके बीच का अंतर यह है कि एक एक फ़ंक्शन है और दूसरा एक क्लास घटक है।
फ़ंक्शन घटक में, मैं {difUser.email} रेंडर कर सकता हूं। जब मैं कक्षा घटक में एक ही काम करने की कोशिश करता हूं, तो मुझे एक त्रुटि मिलती है जो कहती है:
TypeError: null की प्रॉपर्टी 'ईमेल' नहीं पढ़ सकता
यह त्रुटि उसी सत्र से आ रही है जिसमें लॉग इन उपयोगकर्ता है।
नोट: जबकि फायरबेस डॉक्यूमेंटेशन कहता है कि एक करंट संपत्ति प्रॉपर्टी पर उपलब्ध है - मुझे वह काम करने के लिए नहीं मिला है।
मेरे फ़ंक्शन घटक में है:
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 प्रमाणीकृत उपयोगकर्ता के यूआईडी के समान है, इस घटक से, मैं इस उपयोगकर्ता के लिए संग्रह पर ईमेल विशेषता को आउटपुट कर सकता हूँ।
जबकि फायरबेस प्रलेखन उपयोगकर्ताओं को प्रबंधित करने और विशेषताओं तक पहुंचने के लिए यह सलाह प्रदान करता है, मुझे प्रतिक्रिया में इस दृष्टिकोण को लागू करने का कोई तरीका नहीं मिला है। ऐसा करने के प्रयास का प्रत्येक रूपांतर, मेरे फायरबेस में सहायक बनाने से दोनों और घटक में खरोंच से शुरू करने की कोशिश करने से फायरबेस तक पहुंचने में त्रुटियां पैदा होती हैं। हालांकि मैं उपयोगकर्ताओं की सूची और उनके संबंधित उपयोगकर्ता संग्रह की जानकारी का उत्पादन कर सकता हूं (मुझे कोई उपयोगकर्ता नहीं मिल सकता है, जो इस बात पर आधारित हो कि कौन-कौन से उपयोगकर्ता हैं)।
मेरे वर्ग के घटक हैं:
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;
अगले ATTEMPT
यह वास्तव में अजीब है कि इस प्रयास के साथ, मैं उन मूल्यों को सांत्वना देने की कोशिश कर रहा हूं, जिन्हें मैं डेटाबेस में मौजूद देख सकता हूं और नाम के मूल्य को 'अपरिभाषित' के रूप में वापस किया जा रहा है, जहां डीबी में एक स्ट्रिंग है।
इस प्रयास में है:
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);
अगले ATTEMPT
तो यह प्रयास अनाड़ी है और मददगारों या स्नैपशॉट प्रश्नों का उपयोग नहीं करता है जो मैंने ऊपर उपयोग करने की कोशिश की थी, लेकिन उपयोगकर्ता संग्रह दस्तावेज़ विशेषताओं को कंसोल में लॉग इन करें:
{this.props.firebase.db.collection ('उपयोगकर्ता')। doc (difUser.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 ((...) डेटा एक फ़ंक्शन नहीं है।
जब मैं कोशिश करता हूं:
{
this.props.firebase.db.collection('users').doc(authUser.uid).get()
.then(doc => {
console.log(doc.data().name),
<p>doc.data().name</p>
})
}
मुझे एक त्रुटि मिलती है जो कहती है:
लाइन 281: 23: एक असाइनमेंट या फ़ंक्शन कॉल की अपेक्षा की और इसके बजाय एक अभिव्यक्ति देखी-अप्रयुक्त-अभिव्यक्तियाँ नहीं
जब मैं कोशिश करता हूं:
{
this.props.firebase.db.collection('users').doc(authUser.uid).get("name")
.then(doc => {
console.log(doc.data().name),
<p>doc.data().name</p>
})
}
त्रुटि संदेश कहता है:
एक असाइनमेंट या फ़ंक्शन कॉल की अपेक्षा की और एक अभिव्यक्ति देखी
मैं यह जानने की कोशिश करने के लिए तैयार हूं कि स्नैपशॉट प्रश्नों को कैसे प्राप्त किया जाए - अगर मैं स्क्रीन पर प्रस्तुत करने के लिए उपयोगकर्ता संग्रह का नाम प्राप्त कर सकता हूं। क्या कोई उस कदम से मदद कर सकता है?
अगले ATTEMPT
मुझे यह पोस्ट मिली । इसकी एक अच्छी व्याख्या है कि क्या होने की आवश्यकता है, लेकिन मैं इसे लागू नहीं कर सकता जैसा कि दिखाया गया है क्योंकि ComponentsDidMount को यह पता नहीं है कि ओटेरयूज़र क्या है।
मेरा वर्तमान प्रयास इस प्रकार है - हालांकि, जैसा कि वर्तमान में लिखा गया है, ऑर्टयूज़र रिटर्न वैल्यू पर एक आवरण है - और कंपोनेंटडिमाउंट सेगमेंट को यह नहीं पता है कि ऑक्ट्योर क्या है।
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);
अगले ATTEMPT
अगला, मैंने AuthContext.Consumer के अंदर डैशबोर्ड के लिए मार्ग को लपेटने का प्रयास किया ताकि पूरा घटक इसका उपयोग कर सके - जिससे मुझे घटकडाउन फ़ंक्शन में लॉग इन उपयोगकर्ता तक पहुंचने की सुविधा मिल सकती है।
मैंने इसका मार्ग बदल दिया है:
<Route path={ROUTES.DASHBOARD} render={props => (
<AuthUserContext.Consumer>
{ authUser => (
<Dashboard authUser={authUser} {...props} />
)}
</AuthUserContext.Consumer>
)} />
और डैशबोर्ड घटक रेंडर स्टेटमेंट से उपभोक्ता को हटा दिया।
तब डैशबोर्ड घटक पर कंपोनेंटमाउंट में, मैंने कोशिश की:
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 () को गैर-रिक्त स्ट्रिंग के प्रकार के पहले तर्क की आवश्यकता होती है, लेकिन यह था: एक कस्टम डॉक्यूमेंट संदर्भ वस्तु
अगले ATTEMPT नीचे दिए गए लोगों को पहले प्रस्तावित समाधान में कुछ उपयोगी लगता है। मैं इसमें कुछ भी उपयोगी नहीं पा रहा हूं, लेकिन अपने सुझावों के माध्यम से वापस पढ़ रहा हूं, मैं यह देखने के लिए संघर्ष कर रहा हूं कि फायरबेस डॉक्यूमेंटेशन में उदाहरण कैसे है (यह खुलासा नहीं करता है: .doc () अनुरोध के लिए यूआईडी मान कैसे दें ), जो इस प्रकार है:
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!");
}
घटकडाइम समारोह में मेरे प्रयास के लिए मौलिक रूप से भिन्न है, जो है:
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");
}
);
}
शायद उस कदम को हल करना एक सुराग है जो इसे एक परिणाम की ओर ले जाने में मदद करेगा। क्या कोई भी बेहतर फायरस्टार प्रलेखन पा सकता है यह दिखाने के लिए कि उपयोगकर्ता श्रोता यूआईडी में लॉग का उपयोग करके उपयोगकर्ता संग्रह रिकॉर्ड कैसे प्राप्त करें?
उस अंत तक, मैं फ्रेंडलीएट्स कोड लैब उदाहरण से देख सकता हूं कि कोड में आईडी खोज मूल्य के लिए एक doc.id देने का प्रयास है। मुझे नहीं पता कि यह कोड किस भाषा में लिखा गया है - लेकिन यह वही दिखता है जो मैं करने की कोशिश कर रहा हूं - मैं सिर्फ यह नहीं देख सकता कि उस उदाहरण से उस चीज़ तक कैसे जाया जाए जिसे मैं जानता हूं कि कैसे काम करना है।
display: function(doc) {
var data = doc.data();
data['.id'] = doc.id;
data['go_to_restaurant'] = function() {
that.router.navigate('/restaurants/' + doc.id);
};