FIREBASE getting document data - javascript

I'm making an app and trying to get product data by it's id inside a modal in ionic 4.
I'm using typescript to do it but without luck.
Because de calls to firebase are asynchronous i cannot get the data that is held in firebase and also because i'm new to subject i cannot figured out the proper way to write the code.
I read about how to do it but i'm having a hard time to achieve it.
Here is my function that tries to grab product data from firebase.
It always logs empty on console.log('todo', todo).
async editProduct(id) {
const getTodo = docRef => {
setTimeout(() => {
docRef = this.afs.collection("products").doc(id);
docRef.get().subscribe((doc) => {
if (doc.exists) {
let data = doc.data();
return data;
} else {
console.log("No document.");
return false;
}
});
}, 2000)
}
getTodo(todo => {
console.log('todo', todo)
})
const modal = await this.modalCtrl.create({
component: AdminProductPage,
'id': id,
});
await modal.present();
}

There is something wrong with your "getTodo". Probable you are logging empty data with your code, I can give you the proper functional example:
myData
editProduct() {
this.afs.collection("products").doc(id)
.valueChanges()
.subscribe(data => {
console.log(data)
myData = data
})
}
getData() {
console.log(this.myData) // You will log it twice with this line
}
GOOGLE EXAMPLE
docRef.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((error) => {
console.log("Error getting document:", error);
});
https://firebase.google.com/docs/firestore/query-data/get-data?hl=es

Related

How can I pass data retrieved from firestore to varable

I am stuck on probably a very basic thing, but I can't seem to get the data from Firestore into the return variable "profile"
What am I doing wrong when looking at the code below?
let profile;
export const getWidgets = createAsyncThunk(
"projectDashboardApp/widgets/getWidgets",
async () => {
var docRef = db().collection("companies").doc("cmpn0000001");
docRef
.get()
.then((doc) => {
if (doc.exists) {
profile = doc.data()
console.log("Document data:", doc.data());
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}
})
.catch((error) => {
console.log("Error getting document:", error);
});
return profile;
}
);

How to modify and store data, retrieved from an API call, in Firestore correctly

I retrieve data from an API and want to add new properties(comments:[], likes:'', etc.) each of the map. What I tried is that modifying data on UI side, and it didn't effect Firestore side. Even I modify the data on Firestore side by creating new collection it works until I refresh the app. Can you please show me the correct way how to modify and store the data?
const newsFromApiRef = firestore().collection('topHeadlines');
//Adding data to firestore
const newsOnFirebase = async () => {
await getTopHeadlines('us')
.then((data) => {
newsFromApiRef
.doc('testDocUID')
.set(data)
.then(() => {
console.log('Data added succesfully');
})
.catch((error) => {
console.log(error);
});
})
.catch((error) => {
console.log(error);
});
};
//Getting data from firestore, and added new properties
const getFromFirebase = async () => {
await newsOnFirebase();
var data;
await newsFromApiRef
.doc('testDocUID')
.get()
.then((querySnapshot) => {
const newData = [];
querySnapshot.data().articles.forEach((list) => {
if (list?.comments) {
newData.push({ ...list });
} else {
newData.push({
...list,
comments: [],
});
}
});
data = {
articles: [...newData],
status: querySnapshot.data().status,
totalResults: querySnapshot.data().totalResults,
};
})
.catch((error) => {
console.log(error);
});
return data;
};
If you want to get a document's data from Firestore and add new properties to this document, you need to first query for the document (with the get() method), as you do, and then write back to Firestore, either with the update() or set() methods (which you don't do).
Since you are using async/await, you can do along the following lines:
const snap = await newsFromApiRef.doc('testDocUID').get();
const docData = snap.data();
const newData = [];
docData.articles.forEach((list) => {
if (list?.comments) {
newData.push({ ...list });
} else {
newData.push({
...list,
comments: [],
});
}
});
const data = {
articles: [...newData],
status: docData.status,
totalResults: docData.totalResults,
};
await newsFromApiRef.doc('testDocUID').update(data);
Note that since you read one document, you are actually getting a DocumentSnapshot, and not a QuerySnapshot, hence the renaming in my anwser.

My function is being called before the state is changed

I'm working in Reactjs and my database is Firebase.
I'm trying to retrieve data from my database and then checking data regarding it.
At the top, I have const [group, setGroup] = useState(null); for my group data. In my CheckGroupRelationship function, if checks the database using the group object data.
Initially I had the function called after the database call:
const GetGroupInfo = async (uid) => {
await props.firestore
.collection("groups")
.doc(uid)
.get()
.then(async (doc) => {
if (!doc.exists) {
console.log("No such document!");
} else {
setGroup({
id: doc.data().id,
ownerID: doc.data().ownerID,
name: doc.data().name,
});
}
})
.catch((err) => {
console.log("Error getting document", err);
});
CheckGroupRelationship();
};
However, I would get the error "Group is null". So I moved the function called to the setState:
const GetGroupInfo = async (id) => {
await props.firestore
.collection("groups")
.doc(id)
.get()
.then(async (doc) => {
if (!doc.exists) {
console.log("No such document!");
} else {
setGroup(
{
id: doc.data().id,
ownerID: doc.data().ownerID,
name: doc.data().name,
bio: doc.data().bio,
},
CheckGroupRelationship()
);
}
})
.catch((err) => {
console.log("Error getting document", err);
});
};
This would still result in the "group is null" error. I'm not sure what else I can do to get the function to be called AFTER the state is set.
the easy solution would be to use useEffect. In your case you can do this:
const [group, setGroup] = useState(null);
useEffect(() => {
if (group) {
CheckGroupRelationship()
}
}, [group])
What useEffect does here is waiting for group to change and when it changes it calls the inside callback. In this case you will have group updated there. Hope it helps, cheers

Firestore - How to check if a document exist based on a specific field

What I want to achieve is to check if a document exist based on a field like liker_id and if it exist then return and if not then create a new document with the liker_id.
I've tried both snapshot.exists and doc.exists but they seem to give weird behaviors where the console.log doesn't get triggered or collection still adds document even though it already exists.
const liker = db
.collection("post")
.doc('ubxL0nDCLHgrtEyQ5TEV')
.collection("votes")
.where("liker_id", "==", "user-TVe8mMRU47cnfO4xbl9yQEEE4XB3")
.get()
.then(snapshot => {
snapshot.forEach(doc => {
if (doc.exists) {
console.log("exist");
} else {
console.log("not exist");
}
});
})
.catch(error => {
console.log(error);
});
Would you try the code like this?
const liker = db
.collection("post")
.doc('ubxL0nDCLHgrtEyQ5TEV')
.collection("votes")
.where("liker_id", "==", "user-TVe8mMRU47cnfO4xbl9yQEEE4XB3")
.get()
.then(snapshot => {
const data = snapshot.val();
data.forEach(doc => {
if (doc.exists) {
console.log("exist");
} else {
console.log("not exist");
}
});
})
.catch(error => {
console.log(error);
});

Delete Value in AsyncStorage React Native

I have a function for looking item exists or not.
addNewPerson(name) {
AsyncStorage.getItem('savedPersons', (err, result) => {
const name = [name];
if (result !== null) {
var newIds = JSON.parse(result).concat(name);
AsyncStorage.setItem('savedPersons', JSON.stringify(newIds));
console.log('Data Found', result);
} else {
AsyncStorage.setItem('savedPersons', JSON.stringify(name));
console.log('Data Added', name);
}
});
}
Now I want to delete some specific person in "savedPersons".
I Tried this code:
AsyncStorage.removeItem('savedPersons','Uzuner');
error text is : "callback is not a function."
How can I delete item in asycnStorage's array?
Solved:
I write this code for deleting item.
removePost = async (post_id) => {
try {
const posts = await AsyncStorage.getItem('savedPersons');
let postsFav = JSON.parse(posts);
const postsItems = postsFav.filter(function(e){ return e !== post_id });
// updating 'posts' with the updated 'postsItems'
await AsyncStorage.setItem('savedPersons', JSON.stringify(postsItems));
} catch(error) {
console.log('error: ', error);
}};
Thanks alot all users for replies.
AsyncStorage.removeItem is an asynchronous task which returns a promise or callback. Also, if you want to remove an element from the array then you need to get the array first,delete the element and push it back to the local storage. Something like this,
AsyncStorage.getItem("savedPersons")
.then(persons =>{
const index = persons.indexOf("Uzuner");
const modifiedPersons = persons.splice(index,1);
AsyncStorage.setItem("savedPersons",modifiedPersons)
.then(() => console.log(done))
.catch((error) => console.log("error"));
})
.catch(error => console.log("Error while retrieving the savePersons"));

Categories

Resources