Grab from an Object in a collection in firebase - firebase

Traying to grab company ID stored in a user Object in firebase.
const handleSubmit = async (e) => {
e.preventDefault()
setError('')
try {
const { user } = await signIn(email, password)
const userID = await user.uid
const compID = doc(db, 'Users', user.uid)
console.log(userID + ' USERID')
console.log(compID.companyID + ' COMPANYID')
navigate('/Main/Dashboard')
} catch (e) {
setError(e.message)
console.log(e.message)
}
}
Tried logging it and I get undefined. If I put the whole path in the const compID then I get an invalid error due to having and odd number of selectors.

You need to actually fetch the document. What you have done now is create a query but not executing it.
To fetch the user document, do like this instead:
const { user } = await signIn(email, password)
const userID = user.uid
const docRef = doc(db, "Users", userID);
const docSnap = await getDoc(docRef);
if (docSnap.exists()) { // Check if the document exists before accessing data
const data = docSnap.data()
// Access compId by:
const compID = data.companyID
console.log("Here is you company id:", compID);
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}

Related

#react-native-firebase/storage -How to upload Image and get the image url

I can upload Image but can't get url into firestore.
I have tried many other people's methods without success...
const uploadImage = async () => {
setUploading(true);
const response = await fetch(image.uri)
const blob = await response.blob();
const filename = image.uri.substring(image.uri.lastIndexOf('/') + 1);
**const imgurl = await getDownloadURL().catch((error) => { throw error });**
var ref = a.storage().ref('math/' + filename).child(filename).put(blob);
console.log("Document successfully written!")
try {
await ref;
} catch (e) {
console.log(e);
}
setUploading(false);
Alert.alert(
'sucess'
);
setImage(null);
db.collection("imageurl").doc().set({
url:imgurl,
})
}

Firebase listUsers fails to get All users after a certain page

I'm using a pubsub firebase function (cron), and inside this function Im calling firebase auth users, to fill some missing data in a profile collection
Im paginating with the pageToken, the first token passed is undefined then I save it in a config db and read the token to get the next page
The issue is that I have 170K records, and listusers returns an undefined token at the 6th page (6k users) which is frsutrating
here is the code:
functions.pubsub
.schedule('*/30 * * * *')
.onRun(async () => {
const page = firestore.collection('config').doc('pageToken');
const doc = (await page.get()).data();
// Check if last page don't run again
const last = doc?.last;
if (last) return;
// Load page
const pageToken = doc?.pageToken || undefined;
let pageNumber = doc?.pageNumber as number;
return firebaseAdmin
.auth()
.listUsers(1000, pageToken)
.then(async listUsersResult => {
for (const userRecord of listUsersResult.users) {
// Fetch Profile
try {
const profile = await firestore
.collection('profiles')
.doc(userRecord.uid);
// data foramtting here
// compared profile data & fixed data
const payload = JSON.parse(
JSON.stringify({
...profileData,
...{
lastName,
firstName,
language,
...(!userRecord.phoneNumber && {
phone,
}),
},
})
);
// Profile doesn't exist : Create
if (!profileData && payload) {
await profile.create({
...payload,
...{
Migrated: true,
},
});
} else if (profileData && payload) {
const data = compare(profileData, payload);
if (data) {
// Profile exists: Update
await profile.update(data);
if (userRecord.phoneNumber)
await profile.update({
phone: firebaseAdmin.firestore.FieldValue.delete(),
});
}
}
} catch (err) {
functions.logger.error('Some Error', err);
}
}
if (!listUsersResult.pageToken) {
return await firestore
.collection('config')
.doc('pageToken')
.update({
last: true,
});
}
// List next batch of users.
pageNumber++;
return await firestore
.collection('config')
.doc('pageToken')
.update({
pageToken: listUsersResult.pageToken,
pageNumber,
});
});
});
so after in page 6, I have a last:true property added to the firestore however there is 164k data are missing
any idea ?

Firebase Firestore - Displaying Queried Data in React Native

I require some help that I couldn't find easily in the documentation.
So I've gotten my head around how to create a document in firebase on signup and setting the doc's ID to the current users uid. Now I want to reference the current user's doc and use its data throughout screens.
This is the function I use to retrieve the data:
const user = auth.currentUser;
const GettingUserData = async() => {
const userData = firestore.collection('users').doc(user.uid);
const doc = await userData.get();
if (!doc.exists) {
console.log('No such document!');
} else {
console.log('User data:', doc.data());
}
}
how would I go about using the data inside of doc.data() in something like <Text>{data.displayName}</Text>
Help or a link to read through would be greatly appreciated!
To manage remote data, you need a state to store that information.
If you are using a functional component:
const [userData, setUserData] = React.useState(null)
const user = auth.currentUser;
const GettingUserData = async() => {
const userData = firestore.collection('users').doc(user.uid);
const doc = await userData.get();
if (!doc.exists) {
console.log('No such document!');
} else {
console.log('User data:', doc.data());
setUserData(doc.data)
}
}
return (<View><Text>{userData?.name}</Text></View>)
if you are using class components:
const user = auth.currentUser;
const GettingUserData = async() => {
const userData = firestore.collection('users').doc(user.uid);
const doc = await userData.get();
if (!doc.exists) {
console.log('No such document!');
} else {
console.log('User data:', doc.data());
this.setState({userData: doc.data()})
}
}
return (<View><Text>{this.state.userData?.name}</Text></View>)

How can I build a one to one (private) chat application in react native using fire-base as a back-end?

I want to add a chat feature in my application, but the problem is while working with react-native-gifted-chat and firebase as a backend and its secured rules that gives an error of missing _id and user.
I tried using the firebase database and without using secured rules but the issue is it seems to be like a group chat rather than one to one (private) chat.
async UNSAFE_componentWillMount() {
const name = auth().currentUser.displayName;
const friendName = this.state.friendName;
this.setState({ name: name });
const ref = await database().ref(`chatmessages/`);
// Fetch the data snapshot
const snapshot = await ref.once('value');
console.log(snapshot, "Snapshot")
console.log(ref, "database");
}
componentDidMount() {
this.on(message => {
console.log(this.state.messages, 'old message')
this.setState(previousState => ({
messages: GiftedChat.append(previousState.messages, message),
})
)
});
}
componentWillUnmount() {
this.off();
}
get uid() {
return (auth().currentUser || {}).uid;
}
get ref() {
return database().ref(`chatmessages/`)
// .set();
}
parse = async snapshot => {
const data = snapshot.val();
const userID = auth().currentUser.uid;
const friendID = this.state.friendID;
const validate = data.friend === friendID && data.user._id === userID ||
data.user._id === friendID && data.friend === userID;
console.log(data.user, data.user._id, data.user.name, "MEssage Data")
if (validate) {
const { timestamp: numberStamp, text, user, friend } = await data;
const { key: _id } = snapshot;
console.log(_id, user,'Firebase Message Id')
const timestamp = new Date(numberStamp);
const message = {
_id,
timestamp,
text,
user: data.user,
friend
};
console.log(message, "Gifted")
return message;
}
};
on = callback =>
this.ref
.limitToLast(20)
.on('child_added', snapshot => callback(this.parse(snapshot)));
get timestamp() {
return firebase.database.ServerValue.TIMESTAMP;
}
// send the message to the Backend
send = messages => {
for (let i = 0; i < messages.length; i++) {
const { text, user } = messages[i];
const message = {
text,
user,
friend: this.state.friendID,
timestamp: this.timestamp,
};
this.append(message);
}
};
append = message => this.ref.push(message);
// close the connection to the Backend
off() {
this.ref.off();
}
get user() {
return {
name: auth().currentUser.displayName,
_id: this.uid
};
}
render() {
<GiftedChat
text={this.state.text}
onInputTextChanged={text => this.setState({ text: text })}
messages={this.state.messages}
isAnimated
onSend={messages => this.send(messages)}
user={this.user}
renderActions={this.renderCustomActions}
/>
);
}
}
I want a one to one chat created with firebase and react-native-gifted-chat
It's essentially the same except you limit it to just two people. This article explains more on how to handle one to one chat https://medium.com/#edisondevadoss/react-native-chat-using-firebase-d4c0ef1ab0b5

firebase function on db trigger throws Function returned undefined, expected Promise or value

my firebase function based on realtime database trigger looks like below
exports.on_user_created = functions.database.ref("/users/{id}")
.onCreate((change, context) => {
console.log("start of on_user_created ")
const user = change.val();
console.log("New user:::" + JSON.stringify(user))
const uid = user._uid
const referralCode = user._referralCode
console.log("creating referral node for uid:" + uid + " with code:" + referralCode)
if(referralCode === undefined){
console.error("No referral code created for the user while sign up. Referral node cannot be created.")
return true
}
var db = admin.database();
var ref = db.ref('referrals')
ref.child(referralCode).set({"uid": uid}).then(
(resp) => {
console.log("referral node created")
return true
}
).catch(
(err) => {
console.error("unable to create referral node on user create:" + err)
return true
}
)
})
it on run throws
5:47:02.035 AM on_user_created Function returned undefined, expected Promise or value
I am failing to understand why
Adapted following Doug's comment below: "If you have no async work to be done, it's typical to return null"
This is because you don't return the Promise returned by the set() asynchronous operation.
You should do something like:
exports.on_user_created = functions.database.ref("/users/{id}")
.onCreate((change, context) => {
console.log("start of on_user_created ")
const user = change.val();
console.log("New user:::" + JSON.stringify(user))
const uid = user._uid
const referralCode = user._referralCode
console.log("creating referral node for uid:" + uid + " with code:" + referralCode)
if(referralCode === undefined){
console.error("No referral code created for the user while sign up. Referral node cannot be created.")
return null // <-- See Doug's comment below.
}
var db = admin.database();
var ref = db.ref('referrals')
return ref.child(referralCode).set({"uid": uid}).then( // <-- !! Here we return
(resp) => {
console.log("referral node created")
return null
}
).catch(
(err) => {
console.error("unable to create referral node on user create:" + err)
return null
}
)
})
Note that you could streamline your code as follows if you don't need the console.log()s, e.g. for production.
exports.on_user_created = functions.database.ref("/users/{id}")
.onCreate((change, context) => {
const user = change.val();
const uid = user._uid
const referralCode = user._referralCode
if (referralCode === undefined) {
return null;
} else {
var db = admin.database();
var ref = db.ref('referrals')
return ref.child(referralCode).set({"uid": uid});
}
});
For more detail on the importance of returning the promises in a Cloud Function, I would suggest you watch the official video series and in particular the ones titled "Learn JavaScript Promises": https://firebase.google.com/docs/functions/video-series/

Resources