is there a way to get around using 'await' here? - javascript

I am trying to get all the documents in a subcollection by following the firebase documentation, however the error 'await is an reserved identifier' appears.
This is my code currently and I do not see where 'async' could be used with await and the documentation does not indicate that it would be used.
getAuth().onAuthStateChanged((user) => {
if (user) {
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
//reference to the subcollection of subjects in the user's document
const subjectRef = collection(db, "users", auth.currentUser.uid, "subjects");
const querySnapshot = await getDocs(subjectRef);
querySnapshot.forEach((doc) => {
console.log(doc.id, "=>", doc.data());
});
}
});
I have tried getting all the documents with db.collection.('users').document(auth.currentUser.uid).collection('subjects').get() where db = getFirestore(app), however this does not work as the error
'db.collection is not a function' appears and any soloutions I have found to it are not relevant as db is refering firestore not the real time database.

You need to make the callback async:
getAuth().onAuthStateChanged(async (user) => {
if (user) {
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
//reference to the subcollection of subjects in the user's document
const subjectRef = collection(db, "users", auth.currentUser.uid, "subjects");
const querySnapshot = await getDocs(subjectRef);
querySnapshot.forEach((doc) => {
console.log(doc.id, "=>", doc.data());
});
}
});

Related

How search users form firebase

I want search from firstore database user that displayname or nickname contians the search term. I have following code but don't search.
export const searchUsers = async (queryText)=>{
const searchTerm=queryText.toLowerCase();
const usersRef = collection(db, "users");
const users = [];
// Create a query against the collection.
const q = query(usersRef, where("displayName", "array-contains", searchTerm)||where("nickName", "array-contains", searchTerm) ,orderBy("nickName"));
onSnapshot(q, (querySnapshot) => {
querySnapshot.forEach((doc) => { console.log("docsearch:"+doc)
users.push(doc.data());
});
})
return users;
}
I dscoveret that the best way from this issue is make indexes with algolia following the next video: https://www.youtube.com/watch?v=eD1CUWs_3_k&ab_channel=midudev

How to throw an error if firestore document does not exist?

How to throw an error if firestore document does not exist?
const cancel = (id) => {
if(window.confirm("Are you sure to cancel this appointment ?")) {
const userDoc = doc(db, 'accounts', id)
deleteDoc(userDoc)
}
}
you can use the condition if(!userDoc.exist) return ;ยท
it doesn't work for because you need to use it this way
const cancel = (id) => {
if(window.confirm("Are you sure to cancel this appointment ?")) {
const userRef = doc(db, 'accounts', id)
const userDoc = await userRef.get();
if(!userDoc.exist) return console.log("throw an error");
deleteDoc(userRef)
}
}ยท
Your userDoc variable is a reference to a document, it doesn't yet have any data of that document from the database.
If you want to check whether the document exists, you'll first have to get it from the database. From that link comes this code sample, which is quite close to what you're trying to do:
import { doc, getDoc } from "firebase/firestore";
const docRef = doc(db, "cities", "SF"); // ๐Ÿ‘ˆ Create reference
const docSnap = await getDoc(docRef); // ๐Ÿ‘ˆ Load document data
if (docSnap.exists()) { // ๐Ÿ‘ˆ Check if it exists
console.log("Document data:", docSnap.data());
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}

Am new to firebase and cant seem to order my data i have tried using query and orderBy()

i have tried using query and orderBy() and firstly cant even properly fit it into my code
methods:
async saveMessage(){
try {
const docRef = await addDoc(collection(db, "chat"), {
message:this.message,
createdAt: new Date()
});
console.log("Document written with ID: ", docRef.id);
} catch (e) {
console.error("Error adding document: ", e);
}
this.message= null;
},
async fetchMessages(){
const querySnapshot = await getDocs(collection(db,"chat"));
let allMessages = [];
querySnapshot.forEach((doc) =>{
allMessages.push(doc.data());
})
this.messages = allMessages;
}
},
To order results, you add a query with an ordering clause:
import { query, orderBy, ... } from "firebase/firestore";
const querySnapshot = await getDocs(query(collection(db,"chat"), orderBy("name")));
I recommend reading the Firebase documentation on ordering and limiting data, from where I got the changes I made to your code.

Firebase Cloud Function : Cloud Firestore query invalid eventhough data is in Cloud Firestore

I have a cloud function that has the following code. And I call for query from my iOS app. Even though the data is in the Cloud Firestore collection, the function still go to the else statement meaning console print "NOT IN COLLECTION". can someone help?
cloud function code:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
const db = admin.firestore();
const FieldValue = admin.firestore.FieldValue;
exports.validateShop = functions.https.onCall((data, context) => {
const uid = context.auth.uid;
console.log("Function called by UID: " + uid);
const email = context.auth.token.email;
console.log("Email: " + email);
const shop = data.shop;
console.log("Recieved: "+ data);
const docRef = db.collection("Users").where("shopName", "==", shop);
docRef.get().then(function(doc) {
if (doc.exists) {
const docDelete = db.collection("shops").doc(uid);
const updateDoc = docDelete.doc(uid).update({
"shopName": FieldValue.delete(),
});
console.log(shop + ": EXISTS. DOCUMENT UPDATED ");
return {success: true};
} else {
console.log(shop + ": NOT IN COLLECTION ");
return {success: false};
}
}).catch((error) => {
return {"shop": "Error getting document"};
});
return {
message: shop,
};
});
And this is how I call it from my iOS app:
func validateTurn(){
let data = ["shop": "ThaiSook"]
functions.httpsCallable("validateShop").call(data) { (result, error) in
print("Function returned")
if let err = error {print(err)}
if let res = result {print(res)}
}
}
If there is no document at the location referenced by docRef, the resulting document will be empty and calling exists on it will return false.
Aside of double checking the existence of the document you are trying to get, I recommend you to read the example of getting a document from Firestore with Node.js [1].
You may solve your issue by using in your code the keyword await [2].
[1] https://firebase.google.com/docs/firestore/query-data/get-data#get_a_document
[2] https://javascript.info/async-await

Firebase function: cannot read property 'userId' of undefined

im trying to send an email through sendgrid via. a firestore trigger. I just cant seem to get the userId out from my context. Any suggestions?
Image link to error message
exports.firestoreEmail = functions.firestore
.document('users/{userId}')
.onCreate((context) => {
const userId = context.params.userId;
const db = admin.firestore();
return db
.collection("users")
.doc(userId)
.get()
.then((doc) => {
const user = doc.data();
const msg = {
to: user.email,
from: "<myEmail>",
subject: "New Follower",
// custom templates
templateId: "d-1584af76f10d475d8cc99d28e5501cf9",
substitutionWrappers: ["{{", "}}"],
substitutions :{
name: user.displayName
}
};
return sgMail.send(msg);
})
.then(() => console.log("email sent!"))
.catch((err) => console.log(err));
});
context should be the second parameter to your function. It doesn't matter that you named it "context" - the position matters entirely. The first argument is a DocumentSnapshot of the new document, so you'll have to give it name as the first parameter, even if you don't use it:
exports.firestoreEmail = functions.firestore
.document('users/{userId}')
.onCreate((snapshot, context) => {
const userId = context.params.userId;

Categories