Firebase v9 ,Cannot get document from a nested collection - javascript

I feel like it was easier to get subcollection in v8 ,It's been like 2 days trying to do it the new way but I gave up.
Im building a simple react social media app for learning purposes. where each user logs in and be able to post some text (and images but not atm),
I have a main collection for Users and it has the users ID .each of these users have a collection called Posts and it contains all the user posts.
I can do so by entering the UID of each user like so
so what can i do to access the Users collection then get ALL the users and be able to access the Posts subcollection?
ps : sorry if any part of this question is unclear ,english isn't my first language and it's my first time posting here. appreciate any help!.

If you want to fetch posts from all the users, you are looking for collectionGroup queries using which you can fetch documents in all the sub-collections named as 'posts'. You can run a collectionGroup query using Modular SDK (V9) as shown below:
import { getFirestore, getDocs, collectionGroup } from "firebase/firestore"
const db = getFirestore()
const allPosts = await getDocs(collectionGroup(db, "posts"))

const docRef = doc(db, "Users", currentUser.uid);
const docSnap = await getDocs(collection(docRef, "Posts");)

Related

How can I get the id of a inserted document firebase-admin

I am handling some documents with firebase realtime database. I need to delete a document that I don't have the access to read it client side via SDK. In order to do that I need to know what is the id, so I should store it in my db (mongo) and when I need to delete a document on firebase I just get it from my DB and the I delete it.
I took a look to this answer but it doesn't work for me.
I insert documents into my firebase DB with this method (server side using firebase-admin)
const writeNotification = (uid: string, notification: INotification) => {
const db = admin.database();
const notsRef = db.ref(`notifications/${uid}`);
notsRef.push({
..._.omit(notification, 'to'),
});
};
If I do notsRef.id I get undefined.
How can I get the ID of my document that I have just inserted?
p.s. my documents are organized like this:
The answer you are looking at is about Firestore and not Realtime Database that you are using. The Reference has a key property and not id:
console.log('New Key', notsRef.key)
// to get child node's key
const childNotesRef = notsRef.push({
..._.omit(notification, 'to'),
});
console.log(childNotesRef.key)

Firebase 9 get single document from nested collections - React

This is my first time asking a question on here, usually I can find what I'm looking for, but I am upgrading from Firebase 8 to Firebase 9 in an ionic/react FC app, and have got some of it figured out, but I cannot figure out how to get a single document from nested collections. In Firebase 8 it would look like:
db.collection('department').doc(deptId).collection('employees').doc(empId).get()...
I have tried a couple ways with collectionGroup, and don't get anything returned at all, but I'm not even sure that is the correct way to go. Any help would be greatly appreciated!! Thanks!
If you already know syntax (and how Firebase works) of Firebase JS SDK (V8 and before), I'll highly recommend checking out the documentation as they have syntax of both side by side. Just click on the modular tab in documentation. Fetching a single document will be as shown below:
import { doc, getDoc } from "firebase/firestore";
const docRef = doc(db, "department", deptId, "employees", empId);
const docSnap = await getDoc(docRef);
if (docSnap.exists()) {
console.log("Document data:", docSnap.data());
} else {
console.log("No such document!");
}
Also checkout: Firestore: What's the pattern for adding new data in Web v9?

Have an empty docs in querySnaphsot when trying to get data with firebase

I recently developped a firebase schedule function to retrieve data on every monday.
I tested it during the previous days and it was working correctly. However, this morning, I discovered that my query wasn't able anymore to retrieve data as it used to do. I now have an empty array at QuerySnapshot.docs. You can find my code below:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
const db = admin.firestore();
exports.scheduledFunction = functions.pubsub.schedule("0 0 * * 1").onRun(async () => {
console.log("start");
const querySnapshotnext = await db.collection("Next_challenges").orderBy("createdAt").get();
console.log("Let see querySnapshot :", querySnapshotnext); //it works, I can see QuerySnapshot object
console.log("Let see docs :", querySnapshotnext.docs); //have an empty array [] even if it should not, it wasn't empty few days ago
console.log("let see the data of the first doc : ", querySnapshotnext.docs[0].data()); //is of course undefined
return null;
});
You can find my database below with the doc that is normally selected:
The rules of my databases are the following :
I don't really understand why my code isn't working anymore, I think it's certainly related to some parameters stuffs and don't really know how I could debug this by myself so don't hesitate to give me some tips so I can be more autonomous with firebase. Thank you :)
Firestore's documentation has a note that says,
An orderBy() clause also filters for existence of the given field. The result set will not include documents that do not contain the given field.
You have .orderBy("createdAt") in your query but there isn't any createdAt field in the documents (at least the one in screenshot). Did you change your document structure recently that is causing this issue?
Also the Admin SDK bypasses any security rules so I'd recommend setting them to false if you don't need to access data directly from client.

Making a follow system with firestore and cloud functions

Hi I am attempting to make a social media app on Firestore.
Now to model a follow system here is my plan.
users (Collection)
{uid} document which contains Followers and Following as a number.
following (Collection)
{uid}
myFollowing (subCollection)
{uid of other user}
followers (Collection)
{uid}
myFollowers (subCollection)
{uid of other user}
So here is my plan, and please feel free to critique it and help me make it better, because I dont know if this is the best way to do it.
When user A follows user B, I will write a document in:
following
A uid
myFollowing
B uid
This write will happen straight from the app.
After which I plan to trigger a cloud function that does two things, 1. It will increment a counter in the users collection, that holds total following. 2. It will write another document which would be
Followers
B uid
myFollowers
A uid
And after this I can have another cloud function that triggers whenever a document is made in the Followers/uid/myFollowers collection which increments followers count in the users collection.
So here are the questions
Is this the best way to go about this?
How do i write the cloud functions?
Thanks for any help you can give me!
I solved this by doing everything I did above, and using the following code for cloud functions
const functions = require('firebase-functions');
const admin = require("firebase-admin");
admin.initializeApp(functions.config().firebase);
exports.onFollowCreate = functions.firestore
.document("following/{userID}/myFollowing/{id}")
.onCreate((snap, context) => {
const newValue = snap.data()
const db = admin.firestore();
db.collection("users").doc(context.params.userID).update({following: admin.firestore.FieldValue.increment(1)}).catch((er)=>{console.log(er)})
db.collection('followers').doc(newValue.uid).collection("myFollowers").doc(context.params.userID).set({uid: context.params.userID, timeStamp: new Date()}).catch(er=>console.log(er))
});
exports.onFollowDelete = functions.firestore
.document("following/{userID}/myFollowing/{id}")
.onDelete((snap, context)=>{
const deletedValue = snap.data()
const db = admin.firestore();
db.collection("users").doc(context.params.userID).update({following: admin.firestore.FieldValue.increment(-1)}).catch(er=>console.log(er))
db.collection('followers').doc(deletedValue.uid).collection("myFollowers").doc(context.params.userID).delete().catch(er=>console.log(er))
})
exports.onFollowersCreate = functions.firestore
.document("followers/{userID}/myFollowers/{id}")
.onCreate((snap, context)=>{
const db = admin.firestore();
db.collection("users").doc(context.params.userID).update({followers: admin.firestore.FieldValue.increment(1)}).catch(er=>console.log(er))
})
exports.onFollowersDelete = functions.firestore
.document("followers/{userID}/myFollowers/{id}")
.onDelete((snap, context)=>{
const db = admin.firestore();
db.collection("users").doc(context.params.userID).update({followers: admin.firestore.FieldValue.increment(-1)}).catch(er=>console.log(er))
})
I've thought of this before and it was very similar. I think this might be the best way to go about structuring your database. Here's an article on Medium about some database designs.
Now for the functions, you want one which will trigger once you write that document about A following B. See the docs for a onCreate function. Your cloud functions will live in a node.js 10 serverless environment and will have no connection to your front-end application. Here's a real world example of some of my functions on a deployed site. I would recommend not adding data to firestore on your front-end. Instead make a onCall HTTP function, see more about those here.
Sorry for not giving you actual code to go off of, but I find doing it yourself will help you learn. Good luck :)

Finding a specific field in firestore with an id

I know this is a very basic question, but I am new to reactjs and firebase. After two days I am giving up on searching for an answer myself.
I have a firestore database 'MusicList' containing several documents. Within these documents the field 'seperatedStrings' holds (you'll probably will be guessing it) artists and titles of songs.
image of the firestore database
How do I retrive the value a single field (in this example 'seperatedString') using the ID (in this example '5ajnHZ8YDaiYvTAvJ1ec'?
Whenever I am querying for this:
firestore().doc("MusicList/" + "5ajnHZ8YDaiYvTAvJ1ec").seperatedString
the console claims that it is "undefined" (That is a lie!), I'd expect 'Phil Upchurch Blackgold'
Thanks in advance.
You are not using Firebase queries correctly. If you want to fetch a document from a collection, you would do so like this:
firebase
.firestore()
.collection('MusicList')
.doc('5ajnHZ8YDaiYvTAvJ1ec')
.get()
.then(doc => {
if (doc && doc.exists) {
const { separatedString } = doc.data();
//use separatedString
}
});
Check out Firestore - Get A Document for more information.
Also, it would probably be better to structure your documents differently. You could have an artist and track field, and use doc.data().artist and doc.data().track respectively.

Categories

Resources