Firestore can only query collections, not a single document or across arbitrary subpaths.
Here, data is always a single document, not a collection → you can’t directly query /users/*/public/data by username.
If you need to query by username often, store your data like this:
/publicData/{userId}
Each document in publicData contains { username, ... }.
Then you can query:
import { collection, query, where, getDocs } from "firebase/firestore";
import { db } from "./firebase";
// Reference the collection
const publicDataRef = collection(db, "publicData");
// Build a query
const q = query(publicDataRef, where("username", "==", "someUsername"));
// Execute
const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
console.log(doc.id, " => ", doc.data());
});
This works because publicData is now a flat collection.
If you must keep /users/{userId}/public/data, then you can maintain a mirror collection:
/usernames/{username} → { userId }
When you create/update a user, also write to /usernames/{username}.
Then to "query by username," just read /usernames/{username} and get the corresponding userId.
You could read all /users/*/public/data documents and filter client-side by username, but this is inefficient and costly if you have many users.
👉 The best practice:
Either create a flat collection (publicData) or a username index collection (usernames/{username}).