I don't know why mongo mlab _id is not a string? I need to double check context and the viewer._id in my schema. This is my code:
resolve: async ({_id}, {status, ...args}, context) => {
// {_id} destructure _id property on root
console.log("allTodosByUser field = ",_id)
console.log("allTodosByUser field = ",context.user._id)
console.log("allTodosByUser equal",Boolean(_id.toString() === context.user._id.toString())) // suddenly using toString becomes true
This is not really a big deal but somehow I don't want to use toString for comparison:
if(_id.toString() === context.user._id.toString())
So I want to make a function maybe like this:
const { _id, context.user._id: contextUserId } = [_id, context.user._id], // push the _id, and context.user._id in an object so I can destructure?
Related
When trying to deal with an array of references I get the error "FirebaseError: Function Firestore.doc() requires its first argument to be of type non-empty string, but it was: a custom t object"
My user doc has an array of references called reviews and I am trying to get the data of each of the references.
const handleFetch = async () => {
let db = firebase.firestore();
let userRef = await db
.collection("users")
.doc(props.user.id.uid) //<- doc works and returns correctly
.get();
userRef.data().reviews.forEach((ref, indx) => {
let hold = db.doc(ref).get(); //<- error occurs here
});
}
In firestore, a Reference object is constructed into a document or collection reference and you can invoke any of the document methods on it as needed.
const ref = snapshot.data().reviews[0];
ref.get();
ref.remove();
The error in particular is saying that the item is not a string, which if it is a firestore reference, is an object and thus, not compatible.
A great video to watch: https://www.youtube.com/watch?v=Elg2zDVIcLo&t=276s
I'm new to Javascript and react native, and the question itself will be probably very easy to answer.
I'm setting up a AsyncStorage and creating a Item inside the storage, which is a .JSON that has 3 key values to it.
const saveDataToStorage = (token, userId, expirationDate) => {
AsyncStorage.setItem('userData', JSON.stringify({
token: token,
userId: userId,
expiryDate: expirationDate.toISOString()
}))
};
What I want to do now is to retrieve the "userId" value from this item in an other part of the project but here is the problem.
var PersonalId = await AsyncStorage.getItem('userData');
console.log(PersonalId);
console.log(typeof PersonalId);
I know how to access the item itself, but I have no clue how to access the special key inside it. I can not use the command:
var PersonalId = await AsyncStorage.getItem('userData').userId;
because the item from the AsyncStorage is a string, I know this because I got this info from the second line of my code.
console.log(typeof PersonalId);
How can I access the special key "userId" inside my item "userData" and not the whole item itself? I cant work with the item anyways because its a string, I can not treat it as an object and thats my problem.
Thank you for reading and helping out!
You need to first parse value you are getting from the AsyncStorage into a JSON object using JSON.parse(). Try this implementation.
const get_data = async () => {
const userData = await AsyncStorage.getItem("userData");
const userObject = userData !== null ? JSON.parse(userData) : {};
const personalId = userObject.userId;
console.log(personalId);
};
You are forgetting that you stringified the JSON before saving it to storage.. so you are getting string when you read it. Simply JSON.parse the returned string and you should be on your way.
const userData = await AsyncStorage.getItem('userData');
const personalId = JSON.parse(userData).userId;
You should also wrap the above code in a try-catch to make sure you catch errors when invalid data is tried to be parsed and it throws an error.
I'm trying to retrieve a single document by a field value and then update a field inside it.
When I do .where("uberId", "==",'1234567'), I am getting all the docs with field uberId that matches 1234567.
I know for sure there is only one such document. However, I don't want to use uberId as the document's ID, otherwise I could easily search for the document by ID. Is there another way to search for a single document by a field ID?
So far, reading the docs, I could see this:
const collectionRef = this.db.collection("bars");
const multipleDocumentsSnapshot = await collectionRef.where("uberId", "==",'1234567').get();
Then I suppose I could do const documentSnapshot = documentsSnapshot.docs[0] to get the only existing document ref.
But then I want to update the document with this:
documentSnapshot.set({
happy: true
}, { merge: true })
I'm getting an error Property 'set' does not exist on type 'QueryDocumentSnapshot<DocumentData>'
While you may know for a fact there's only one document with the given uberId value, there is no way for the API to know that. So the API returns the same type for any query: a QuerySnapshot. You will need to loop over the results in that snapshot to get your document. Even when there's only one document, you'll need that loop:
const querySnapshot = await collectionRef.where("uberId", "==",'1234567').get();
querySnapshot.forEach((doc) => {
doc.ref.set(({
happy: true
}, { merge: true })
});
What's missing in your code is the .ref: you can't update a DocumentSnapshot/QueryDocumentSnapshot as it's just a local copy of the data from the database. So you need to call ref on it to get the reference to that document in the database.
async function getUserByEmail(email) {
// Make the initial query
const query = await db.collection('users').where('email', '==', email).get();
if (!query.empty) {
const snapshot = query.docs[0];
const data = snapshot.data();
} else {
// not found
}
}
Currently cleaning up a bit of code and rewritting a lot in typescript. What I found what made me curious is the following code:
const userRef = firestore.collection('users').doc(userId);
const userDoc = await userRef.get();
if (userDoc.exists) {
const userData = userDoc.data();
const currentUserBalance = userData.balance ? userData.balance : 0;
}
Now Typescript will complain that userData is possibily undefined, but the Documents .data() cannot be undefined when I check for the document existing above in my if block. Just curious on why that happens and if I have a logic issue here or not.
TypeScript doesn't have any knowledge of the relationship between exists and data(). It just knows the signature of data() says that the return value can be DocumentSnapshot or undefined. So, you must satisfy the compiler by either:
First checking for "truthiness", then use the results if so:
const data = userDoc.data()
if (data) {
// In this block, data is now typed as just DocumentData,
// undefined is no longer an option.
}
Telling TypeScript that you know for sure that the results will be "truthy" by using the ! operator:
const data = userDoc.data()! // data is now typed as just DocumentData
Unfortunately, even though Firestore adapters both for Node.js and the web are written mainly in TypeScript, they aren't designed for the language.
To solve the problem, I wrote Typesaurus, TypeScript-first ORM (or ODM if you wish) that solves this problem:
import { get, collection } from './src'
type User = { name: string }
const users = collection<User>('users')
async function main() {
const user = await get(users, 'qwe') // get will return document or undefined
if (user) {
console.log(user.data.name) // user is Doc<User>
} else {
// user is undefined
}
}
main()
I have been trying to use Firebase Functions to write a simple method, but I am unfamiliar with JS.
Below is the structure of my Realtime Database
-spots
---is_hidden: false
---likes
------like_id_1: true
---dislikes
------dislike_id_1: true
I am trying to write a simple method that does the following: Whenever an entry is added to dislikes, count the likes and the dislikes.
If the number of dislikes is larger than the number of ( likes + 5 ),
change the value of is_hidden to true
This is my attempt to solving the problem
exports.checkHiddenStatus = functions.database.ref('/spots/{spotid}').onWrite(
(change, context) => {
const collectionRef = change.after.ref;
const isHiddenRef = collectionRef.child('is_hidden');
const likesRef = collectionRef.child('likes');
const dislikesRef = collectionRef.child('dislikes');
if(isHiddenRef.before.val()) return;
let likeCount = likesRef.numChildren();
let dislikeCount = dislikesRef.numChildren();
let isHidden = false;
if( dislikeCount >= (likeCount + 5))
isHidden = true;
if(!isHidden) return;
// Return the promise from countRef.transaction() so our function
// waits for this async event to complete before it exits.
return isHiddenRef.transaction((current) => {
return isHidden;
}).then(() => {
return console.log('Counter updated.');
});
});
Sadly, because I have no experience with JS I keep getting stuck with error messages I don't understand. The most recent being
TypeError: Cannot read property 'val' of undefined
at exports.checkHiddenStatus.functions.database.ref.onWrite (/user_code/index.js:28:28)
Can somebody please help me write this function? Thank you!
It looks like you're trying to treat a database Reference object like a Change object. Change has before and after properties, but a reference does not.
If you have a database reference object, and you want the value of the database at that location, you need to query it with its once() method.
Read more about reading and writing data using the Admin SDK.