How delete firestore document - javascript

I use this code below and run well in Firebase RealTime Database:
const onDelete = (id) => {
if (
window.confirm("Are you sure that you wanted to delete the contact ?")
) {
Db.child(`contacts/${id}`).remove((err) => {
if (err) {
alert(err);
} else {
alert("Contact Deleted Successfully");
console.timeStamp(id);
}
});
}
};
Now I create another database in Firebase Firestore but cannot delete.
const onDelete = (id) => {
if (window.confirm("Are you sure that you wanted to delete contact ?")) {
firebase
.firestore()
.collection("contacts")
.doc(`${id}`)
.delete()
.then(() => {
console.log("Document successfully deleted!");
})
.catch((error) => {
console.error("Error removing document: ", error);
});
}
};

There's no difference in the databases here: in both cases you have to specify the full path to the data to be deleted.
If you can somehow specify line numbers for the Realtime Database, most likely you've used those line numbers as keys in your database. And if you can't do the same on Firestore, it's likely you didn't use the line numbers as document IDs there. If that is indeed the case, you'll need to either maintain a mapping from line numbers to document IDs, or use the line numbers for the document IDs in Firestore too.

const onDelete = async (id) => {
if (
window.confirm("Are you sure that you wanted to delete the contact ?")
) {
firebase
.firestore()
.collection("contacts")
.get()
.then(async (querySnapshot) => {
await deleteDoc(doc(db, "contacts", querySnapshot.docs[id].id));
alert("Contact Deleted Successfully");
});
}
};

Related

Trouble batch setting a document field by docId in Firestore

I have been using firebase (firestore) for a while but I'm a little stuck and was wondering if anyone can think of a solution.
On the firestore DB I have a single collection of users, each user has an email address and several other fields. In this instance I am checking if a user email exists and if it does, I want to create a list field for that particular user with a listUid. I am referencing the users by email, grabbing the docId for those users and then trying to set a list field for each of them.
I am not getting any error's from firestore, it's simply not updating in the DB for some reason and I can't figure out where I am going wrong. Thanks in advance
export const addListUidToExistingUserList = (
{ firestore },
emailArray,
listUid
) => {
return async () => {
let docIds = [];
emailArray.forEach((emailAddress) => {
//find users by email (works)
const query = db
.collection("users")
.where("email", "==", emailAddress);
//get docId's for user with matching email (works)
query.get().then((querySnapshot) => {
querySnapshot.forEach((doc) => {
docIds.push(doc.id);
});
});
//add a new list with corresponding listUid (does not work)
docIds.forEach((id) => {
let userRef = db.collection("users").doc(id);
batch.set(userRef, { lists: [{ listUid }] });
});
});
return await batch.commit();
};
};
You are running into this issue because your docIds array is always empty at the time you call docIds.forEach.
That's because query.get().then runs asynchronously, and so docIds.forEach is not waiting for it to complete.
You could either:
await query.get().then; or
Add the docIds.forEach function INSIDE the then callback of query.get.
Here are your possible fixes:
await query.get().then
//get docId's for user with matching email (works)
await query.get().then((querySnapshot) => {
querySnapshot.forEach((doc) => {
docIds.push(doc.id);
});
});
OR:
docIds.forEach inside then
//get docId's for user with matching email (works)
query.get().then((querySnapshot) => {
querySnapshot.forEach((doc) => {
docIds.push(doc.id);
});
docIds.forEach((id) => {
let userRef = db.collection("users").doc(id);
batch.set(userRef, { lists: [{ listUid }] });
});
});
Note: Of course, you could also add batch.set directly into your first iteration of querySnapshot.docs.forEach to prevent an unnecessary iteration.

How to compare a value stored in Firebase in a if statement?

I've been searching and looking for an answer everywhere for days and still can't figure this out.
First let me show you what i want to achieve, here is the picture of the program:
And here is the picture of my Firestore database:
I want to be able and check if the user puts in the roomID in this case 5575 like in the picture above, the program should first check if that roomID exists in the firestore database. When i click the button Join i dont get anything in the console.
Here is my code so far:
const name12 = document.getElementById("oponentname") ;
const roomid = document.getElementById("idinput");
const joinButton = document.getElementById("joinButton");
var firebaseConfig = {
my configuration is here
}
firebase.initializeApp(firebaseConfig);
const db = firebase.firestore();
joinButton.addEventListener("click", function(){
if (roomid.value == db.collection('game').doc(roomid.value).get()) {
console.log("Succes");
}
});
I think you should fix it like this:
db.collection("game")
.doc(roomid.value)
.get()
.then((doc) => {
if (doc.exists) {
console.log("Document data:", doc.data());
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}
})
.catch(function (error) {
console.log("Error getting document:", error);
});
You can read more here
You have to query for documents with that roomID and then check if one matches.
const get_room = (id) => {
return db.collection('game')
.doc(id)
.get()
.then(function(doc) {
return doc.exists
})
.catch(function(err) {
console.log(err)
})
Note that this is an async function, so to check if the inputed room id exists you should use a promise or async/await. My implementation uses promises.
joinButton.addEventListener("click", function(){
get_room(roomid.value).then((doc) => { if (doc) console.log("Succes"); })
});

Firebase Cloud Firestore Read-Write Data

i am trying to signup and save user info into firestore. Save operation is fine but i want to search that info but nothing happening. Here is my code
Signup
firestore
.collection("users")
.doc(user.userId)
.collection("profile")
.add({ ...user })
.then(() => {
auth.onAuthStateChanged((u) => {
if (u) {
u.updateProfile({
displayName: user.displayName,
});
}
});
});
Fetch All users data
firestore
.collection("users")
.get()
.then(function (querySnapshot) {
querySnapshot.forEach(function (doc) {
//doc.data() is never undefined for query doc snapshots
console.log(doc.id, " => ", doc.data());
});
});
You should be able to achieve by using a similar code as the below one. It very similar to yours, but with some differences, where we separate the referencing to the database and let the querySnapshot iterates by itself, so the data can be returned. I usually use this format to return data from collections.
var db = admin.firestore()
var usersReference = db.collection("users");
usersReference.get().then((querySnapshot) => {
querySnapshot.forEach((userDoc) => {
console.log(userDoc.id)
var userDocData = userDoc.data()
console.dir(userDocData)
})
})
This should work, so, in case it doesn't return anything, probably your saving opearation is not working properly. This will return both the user's id and the whole data from it.

Add Payment source to Stripe with firebase-cloud-functions?

I'm trying to integrate stripe payment with my firestore firebase database. I'm having trouble figuring out add payment source function given in the firebase doc example. What am I missing here?
exports.addPaymentSource = functions.firestore
.document('Customers/{userId}/paymentSources/{paymentId}')
.onWrite((change, context) => {
let newPaymentSource = change.after.data();
if (newPaymentSource === null){
return null;
}
return admin.firestore().collection("Customers").doc(`${context.params.userId}`).get('customer_id')
.then((snapshot) => {
return snapshot.val();
}).then((customer) => {
return stripe.customers.createSource(customer, {newPaymentSource});
}).then((response) => {
return change.after.ref.parent.set(response);
}, (error) => {
return change.after.ref.parent.child('error').set(userFacingMessage(error));
}).then(() => {
return reportError(error, {user: context.params.userId});
});
});
I tried
console.log(snapshot.val())
and it gives me a type error.
Firestore database Image
Error Log Image
You're reading from Cloud Firestore, yet are using variable names and method calls that are for the Realtime Database. While both databases are part of Firebase, they're completely separate, and have different APIs.
The equivalent code for Firestore would be:
return admin.firestore().collection("Customers").doc(`${context.params.userId}`).get()
.then((doc) => {
return doc.data();
}).then((customer) => {
...
Also see:
the documentation on reading a document

Cloud Functions for Firebase: how to use a Transaction promise?

I am trying to write a function in Cloud Functions that triggers every time a user gets created and which then saves that user into a list of users and finally increments a user counter.
However I am not sure if I am using promises correctly.
exports.saveUser = functions.auth.user().onCreate(event => {
const userId = event.data.uid
const saveUserToListPromise = db.collection("users").doc(userId).set({
"userId" : userId
})
var userCounterRef = db.collection("users").doc("userCounter");
const transactionPromise = db.runTransaction(t => {
return t.get(userCounterRef)
.then(doc => {
// Add one user to the userCounter
var newUserCounter = doc.data().userCounter + 1;
t.update(userCounterRef, { userCounter: newUserCounter });
});
})
.then(result => {
console.log('Transaction success!');
})
.catch(err => {
console.log('Transaction failure:', err);
});
return Promise.all([saveUserToListPromise, transactionPromise])
})
I want to make sure that even if many users register at once that my userCounter is still correct and that the saveUser function won't be terminated before the transaction and the save to the list has happened.
So I tried this out and it works just fine however I don't know if this is the correct way of achieving the functionality that I want and I also don't know if this still works when there are actually many users triggering that function at once.
Hope you can help me.
Thanks in advance.
The correct way to perform multiple writes atomically in a transaction is to perform all the writes with the Transaction object (t here) inside the transaction block. This ensures at all of the writes succeed, or none.
exports.saveUser = functions.auth.user().onCreate(event => {
const userId = event.data.uid
return db.runTransaction(t => {
const userCounterRef = db.collection("users").doc("userCounter")
return t.get(userCounterRef).then(doc => {
// Add one user to the userCounter
t.update(userCounterRef, { userCounter: FirebaseFirestore.FieldValue.increment(1) })
// And update the user's own doc
const userDoc = db.collection("users").doc(userId)
t.set(userDoc, { "userId" : userId })
})
})
.then(result => {
console.info('Transaction success!')
})
.catch(err => {
console.error('Transaction failure:', err)
})
})

Categories

Resources