I'm trying to display the data from Firestore order by timestamp descending order, I follow the documentation but it seems that I did something wrong.
This is my try:
const outputSnapShot = {};
this.subscribe = firebase
.firestore()
.collection('orders')
.where('restaurant_code', '==', this.state.restaurantCode)
.orderBy('timestamp', 'desc')
.onSnapshot((doc) => {
doc.docs.map(function(documentSnapshot) {
return (outputSnapShot[documentSnapshot.id] = documentSnapshot.data());
});
if (this._isMounted) {
this.setState({ dataSource: Object.entries(outputSnapShot) });
}
});
the result from previous code is the data order by id ASC , Also I finish the INDEXING from Firebase console like so:
I hope I explained the issue clearly.
Thanks
With a help by my friend, we came with this solution and made the code work as we expected:
Going to share this:
this.subscribe = firebase
.firestore()
.collection('orders')
.where('restaurant_code', '==', this.state.restaurantCode)
.orderBy('timestamp', 'desc')
.onSnapshot((docSnapshot) => {
const dataSource = [];
docSnapshot.forEach((doc) => {
dataSource.push(doc.data());
});
if (this._isMounted) {
this.setState({ dataSource });
}
});
I have faced the same problem, in my case the following way worked for me
firebase.initializeApp(firebaseConfig);
var db = firebase.firestore();
var docRef = db.collection('Users').doc('001').collection('Data').orderBy("Date", "desc")
...
Related
I'm trying to replace below code (ver8) to firebase SDK ver9 (modular style). but no success so far.
useEffect(() => {
const unsub = db
.collection("posts")
.doc("postId")
.collection("comments")
.orderBy("timestamp", "desc")
.onSnapshot((snapshot) => {
//update some state
});
return () => {
unsub();
};
}, []);
I tried to use query to access this sub collection together with orderBy by refer to following official example but couldn't find working solution, especially how to handle sub collection reference in query. (how can I realize "collection().doc().collection().orderBy().onSnapshot" in ver9 ?)
I'm really appreciated if someone give me a hint. BR
https://firebase.google.com/docs/firestore/query-data/listen
https://firebase.google.com/docs/firestore/query-data/order-limit-data
As far as I can see in the documentation for the collection function, you can pass in the entire path as a string.
So that should be something like:
...
const db = getFirestore();
const commentsRef = doc(db, "posts", postId, "comments");
#Frank-san Thank you very much for your hint. Now everything working fine with full path arguments (your hint) as like below.
useEffect(() => {
const q = query(
collection(db, "posts", props.postId, "comments"),
orderBy("timestamp", "desc")
);
const unSub = onSnapshot(q, (snapshot) => {
//Some process
});
return () => {
unSub();
};
}, []);
Thanks again and have a good day !
When removing an item from my RTDB, my intention is to clean up user's likes if the item they like got removed.
With my data structure like so:
I am attempting to remove the nodes like this:
const updates = {};
//WORKS
updates[`/strains/${title}/`] = null;
updates[`/strainsMin/${title}/`] = null;
firebase
.database()
.ref('reviews')
.orderByChild('s')
.equalTo(title)
.once('value', snapshot => {
console.log(snapshot.val())
snapshot.forEach(child => {
console.log(child.key)
//WORKS
updates[`/reviews/${child.key}`] = null;
});
})
.then(() => {
firebase
.database()
.ref('userLikedStrains')
.orderByChild(title)
.equalTo(title)
.once('value', snapshot => {
console.log(snapshot.val() + 'likeylikeyyy')
snapshot.forEach(child => {
console.log(child.key)
//DOESNT WORK
updates[`/userLikedStrains/${child.key}/${title}`] = null;
});
firebase
.database()
.ref()
.update(updates);
})
For some reason this doesn't work. Is it because I am targeting a key (which is still a child?..)
I appreciate any help with this!
Cheers.
The code you shared is not writing anything back to the database yet. For that you need to call update after the loop.
Something like:
let ref = firebase
.database()
.ref('userLikedStrains');
ref.orderByChild(title)
.equalTo(title)
.once('value', snapshot => {
console.log(snapshot.val())
snapshot.forEach(child => {
console.log(child.key)
updates[`/userLikedStrains/${child.key}/${title}`] = null;
});
ref.update(updates);
})
I am querying firebase firestore by...
let database = firebase.firestore();
let places = database.collection("place");
console.log("places", places);
now the logged data is bizarre and not the actual documents..
here is a picture of the log...can you please advice regarding tackling this ?
If you want to retrieve all items in your collections called "place" you can do something like this:
let database = firebase.firestore();
let places = database.collection("place");
const querySnapshot = places.get()
// You can make an empty array to eventually push the items into
const collectionArray = []
querySnapshot.forEach((doc) => {
const data = doc.data()
collectionArray.push(data)
}).catch(function(error) {
console.log("Error getting documents: ", error);
})
console.log('collectionArray:',collectionArray)
}
Your code hasn't actually executed any query yet. All it's done is build a Query object.
If you want to execute the query, call get() on it, and handle the results as shown in the documentation.
let database = firebase.firestore();
let query = database.collection("place");
query.get()
.then(querySnapshot => {
querySnapshot.forEach(documentSnapshot => {
console.log("document", documentSnapshot.data());
})
})
I need help, i'm trying to update my comments collections using cloud function, but my code doesn't seem to work. My function succesfully run but doesn't update my avatarUrl when my userPhotoUrl is update
Here the whole path of the collection that i want to update : "/comments/{postId}/comments/{commentId}"
my firestore collection
exports.onUpdateUser2 = functions.firestore
.document("/users/{userId}")
.onUpdate(async (change, context) => {
const userUpdate = change.after.data();
const userId = context.params.userId;
const newPhotoUrl = userUpdate.photoUrl;
console.log("userId",userId);
console.log("newPhotoUrl",newPhotoUrl);
const querySnapshot = await admin.firestore().collection("comments").get();
querySnapshot.forEach(doc => {
console.log("doc",doc.data());
const postId = doc.id;
const comments = admin.firestore().collection("comments").doc(postId).collection("comments").where("userId","==",userId).get();
comments.forEach(doc2 => {
return doc2.ref.update({avatarUrl: newPhotoUrl});
});
});
});
Thank you,
UPDATE
I try to change the code, by using then to deal with these various promises but i don't really know why commentsRef.get() seem to return me empty querySnapshots, because the comments collections in my firestore database have multiple documents where in each documents there is a another comments collections where in this seconds comments collections there is a bunch of documents containing data. With this whole path i don't know how to iterate until being in the documents containing the data that i need to update. Can someone help me please ?
exports.onUpdateUserUpdateComments = functions.firestore
.document("/users/{userId}")
.onUpdate(async (change, context) => {
const userUpdate = change.after.data();
const userId = context.params.userId;
const newPhotoUrl = userUpdate.photoUrl;
console.log("userId",userId);
console.log("newPhotoUrl",newPhotoUrl);
const commentsRef= admin.firestore().collection("comments");
return commentsRef.get().then(querySnapshot => {
return querySnapshot.forEach(doc => {
return admin
.firestore()
.collection("comments")
.doc(postId)
.collection("comments")
.where("userId", "==", userId)
.get()
.then(doc => {
if (doc.exists) {
doc.ref.update({avatarUrl: newPhotoUrl});
}
return console.log("The function has been run.");
});
});
});
});
Without trying it, it should be something like this:
return admin.firestore().collection("comments")
.doc(postId)
.where("userId", "==", userId)
.get()
.then(doc => {
if (doc.exists) {
doc.ref.update({avatarUrl: newPhotoUrl});
}
return console.log("The function has been run.");
});
Regardless, following Doug Stevenson's advice, you shouldn't start learning JS in Cloud Functions, as those nested loops are a bit strange and you may lack a good starting point for learning.
I am transitioning a Firebase real-time database to a Firebase Firestore database but am having trouble finding the appropriate reference to query the current user.
onAuthUserListener = (next, fallback) =>
this.auth.onAuthStateChanged(authUser => {
if (authUser) {
this.user(authUser.uid)
.once('value')
.then(snapshot => {
const dbUser = snapshot.val();
// 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();
}
});
Most specifically, what would be the replacement for once('value') and snapshot.val();?
I had thought that
.onSnapshot(snapshot => {
const dbUser = snapshot.val();
...
The equivalent of once('value' in Firestore is called get(), and the equivalent of val() is data(). Calling get() returns a promise, so:
.get().then(snapshot => {
const dbUser = snapshot.data();
...
If you have a collection of users, where the profile of each user is stored within a document with their UID as its ID, you can load that with:
firebase.firestore().collection('users').doc(authUser.uid)
.get()
.then(snapshot => {
const dbUser = snapshot.val();
Note that this is pretty well covered in the documentation on getting data, so I'd recommend spending some time there and potentially taking the Cloud Firestore codelab.