Hello I am new to react native and particullary firebase. I've been watching tutorial about using firebase with react native and i read the react native firebase documentation but i am stuck. I have data in my firestore data base, in my collection called user but I am not able to read, to get the data from it. Here is my firestore database :
and here is how I tried to get the data in my component :
const Profile = ({navigation, ...props}) => {
async function getUserData () {
const userCollection = await await firebase.firestore().collection('users').doc(firebase.auth().currentUser.uid).get()
return userCollection
}
console.log('🐲' + getUserData())
this return me that : [object Object]
I also tried this, (it was how it was done in the instagram clone tutorial of Adrian Twarog) :
const Profile = ({navigation, ...props}) => {
function getUserDataFirstTry() {
firebase.firestore()
.collection("users")
.doc(firebase.auth().currentUser.uid)
.get()
.then((snapchot) => {
if(snapchot.exists){
console.log('🦜' + snapchot.data())
} else {
console.log('merde ca marche pas')
}
})
}
console.log('🐲🐲' + getUserDataFirstTry())
But I get the same result in my console : [object Object]
I tried to put my function in a useEffect hook but this changes nothing.
Can you tell me what I am doing wrong ? (if possible in the second example because it's realtime changes). Thanks.
As Nicholas commented, since you're concatenating snapchot.data() to a string, you get the string representation of that object, which is pretty useless.
To log a specific field from the data:
console.log('🦜' + snapchot.data().userName)
To log all fields from the data in a more useful format:
console.log('🦜' + JSON.stringify(snapchot.data()))
Note: the proper spelling is snapshot (not snapchot), but I kept your original spelling here for ease of copy/paste.
Related
I use firebase firestore db. This project have two main collection "securecollection" and "publiccollection". The securecollection is where all important data is stored and only accessible to authenticated users. But in order for some information to be visible to guest users, I am copying them into the publiccollection. Then, I want to save the id of this newly created public document in the secure document.
When I write a variable
db.collection('securecollection').doc(secureDocid).update({ inside the query sentence, I get this error:
Uncaught (in promise) TypeError: o.indexOf is not a function
If I write the id as text db.collection('securecollection').doc('7llDqIWlmE5VM69Zzle2').update({, the code works.
Here is my code:
function toggleOlustur(secureDocid) {
const db = firebase.firestore();
db.collection("securecollection").get()
.then(querySnapshot => {
querySnapshot.forEach(doc => {
if (doc.id == secureDocid) {
db.collection("publiccollection").add({
oad: doc.data().oad,
osad: doc.data().osad,
opuan: doc.data().opuan,
odtarih: doc.data().odtarih,
odurum: "1",
})
.then((docRef) => {
db.collection('securecollection').doc(secureDocid).update({
preference: docRef.id
})
});
}
});
});
}
The doc() method expects a string argument, and from the error message it sounds like your secureDocid is not a string value. If you console.log(JSON.stringify(secureDocid)) you can see what it outputs, which might help to figure out the problem.
I'm quite new to performing firebase realtime database queries and react native. I have a list of users in my realtime database and some of the users have a list of properties as shown below. I would like to obtain these properties as well as the users of the properties and place it into an array using react native. I'm not to sure how to do this.
This is what I have so far:
database().ref(`users/`).once(`value`, snapshot =>{
snapshot.forEach(function(childSnapshot){
if(childSnapshot.val().properties != null) {
}
});
I would like the error to be displayed as:
[{uid1,property1}, {uid1,property2}, {uid2,property1}, {uid2,property2}, {uid2,property3},...., {uidX,propertyX}]
})
I find that in cases like this, it really helps to give your variables good names:
database().ref(`users/`).once(`value`, snapshot =>{
let properties = [];
snapshot.forEach((userSnapshot) => {
if (userSnapshot.hasChild("properties")) {
userSnapshot.child("properties").forEach((propertySnapshot) => {
properties.push({
uid: userSnapshot.key,
property: propertySnapshot.val()
})
})
}
});
console.log(properties);
});
Isn't it true that you could miss data if what you are ordering by does not have a unique value?
For example if I have a function that says:
export async function getCities(){
const result = await firebase
.firestore()
.collection('cities')
.orderBy('population', 'desc')
.limit(5)
.get();
const CityResults = result.docs.map((city)=> ({
...city.data(),
docId: city.id
}));
if I limit to 5 and my last piece of data has a population of 1000, my getMoreCities() funciton would say
startAfter(1000)
But say there were 7 cities with a population of exactly 1000, you would miss the data on both of your firestore calls.
It seems silly you cant startAfter(documentId)
is there a workaround?
Firestore implicitly adds the document ID to each query where you specify an anchor document, so if you pass in a DocumentSnapshot it will already work.
You should also be able to pass the document ID as the last argument to your startAfter variant, although I must admit I always use the DocumentSnapshot for this purpose myself.
Here's an example of what this would look like:
citiesRef.orderBy("population").startAt(860000).limit(1).get().then((snapshot) => {
var lastdoc;
snapshot.forEach(function(doc) {
console.log("1: "+doc.id);
lastdoc = doc;
});
citiesRef.orderBy("population").startAfter(lastdoc).limit(1).get().then((snapshot) => {
snapshot.forEach(function(doc) {
console.log("2: "+doc.id);
lastdoc = doc;
});
});
});
Working version: https://jsbin.com/sibimux/edit?js,console
I am new to React Native, please provide some Github link or your own code for reference. Consider me as a beginner in RN.
I found very less open support for RN, Mobx State tree, Ignite and all, so not just post and get API reference, if you find anything helpful related to these above-mentioned topics, Feel free to share.
Thanks in advance.
Mobx State Tree, With Ignite Bowler you would have api.ts file where you can specify API calls.
async getUser(userToken: string): Promise<Types.GetUserResult> {
// make the api call
const response: ApiResponse<any> = await this.apisauce.post(`api/v1/sales/login?authCode=${userToken}`)
if (!response.ok) {
const problem = getGeneralApiProblem(response)
if (problem) return problem
}
// transform the data into the format we are expecting
try {
try {
const rawUser = response.data
console.log('rawUser'+ rawUser)
const user: UserSnapshot = convertRawUserToUserStore(rawUser)
return { kind: "ok", user }
console.log({ user })
} catch (e) {
__DEV__ && console.tron.log(e.message)
return { kind: "bad-data" }
}
} catch {
return { kind: "bad-data" }
}
}
Consider, we will be getting user data from this API call,
you can notice that there is UserSnapshot which belongs to User Model, Snapshot will save the data automatically, you don't need Aysnc storage to save or retrieve data.
This is the method I'm using, pretty simple.
DailyCountTest: function (){
this.$store.dispatch("DailyCountAction")
let NewPatientTest = this.$store.getters.NewPatientCountGET
console.log(NewPatientTest)
}
The getter gets that data from a simple action that calls a django backend API.
I'm attempting to do some charting with the data so I need to assign them to variables. The only problem is I can't access the variables.
This is what the console looks like
And this is what it looks like expanded.
You can see the contents, but I also see empty brackets. Would anyone know how I could access those values? I've tried a bunch of map.(Object) examples and couldn't get any success with them.
Would anyone have any recommendation on how I can manipulate this array to get the contents?
Thanks!
Here is the Vuex path for the API data
Action:
DailyCountAction ({ commit }) {
axios({
method: "get",
url: "http://127.0.0.1:8000/MonthlyCountByDay/",
auth: {
username: "test",
password: "test"
}
}).then(response => {
commit('DailyCountMutation', response.data)
})
},
Mutation:
DailyCountMutation(state, DailyCount) {
const NewPatientMap = new Map(Object.entries(DailyCount));
NewPatientMap.forEach((value, key) => {
var NewPatientCycle = value['Current_Cycle_Date']
state.DailyCount.push(NewPatientCycle)
});
}
Getter:
NewPatientCountGET : state => {
return state.DailyCount
}
State:
DailyCount: []
This particular description of your problem caught my eye:
The getter gets that data from a simple action that calls a django backend API
That, to me, implies an asynchronous action and you might be getting a race condition. Would you be able to post a sample of your getter function to confirm my suspicion?
If that getter does indeed rely on an action to populate its contents, perhaps something to the effect of the following might do?
DailyCountTest: async () => {
await this.$store.dispatch('DailyCountAction')
await this.$store.dispatch('ActionThatPopulatesNewPatientCount')
let NewPatientTest = this.$store.getters.NewPatientCountGET
// ... do whatever with resulting array
}
You can also try with a computer property. You can import mapGetters
import { mapGetters } from 'vuex'
and later in computed properties:
computed: {
...mapGetters(['NewPatientCountGET'])
}
then you can use your NewPatientCountGET and it will update whenever the value changes in the store. (for example when the api returns a new value)
Hope that makes sense