Firebase firestore - Data must be an object, but it was: a custom Object object - javascript

I'm using Firestore in conjunction with realtime database in order to provide a user presence system for my application.
Update: article I followed
https://blog.campvanilla.com/firebase-firestore-guide-how-to-user-presence-online-offline-basics-66dc27f67802
In one of the methods I use this code here:
const usersRef = this.$fireStore.collection('users').doc(uid)
const whoIsOnlineRef = this.$fireDb.ref('.info/connected')
whoIsOnlineRef.on('value', (snapshot) => {
this.$fireDb.ref(`/status/${uid}`)
.onDisconnect()
.set('offline')
.then(() => {
usersRef.set({ online: true }, { merge: true })
this.$fireDb.ref(`/status/${uid}`).set('online')
})
})
The .set method, however, is giving me the error mentioned in the title and I can't quite understand why. I'm simply passing a javascript object to .set method and this should technically work.
Can you spot what is wrong with the code?

Looks like the reason why this wasn't working is that the code was running on the server in an SSR application.
I moved that very same logic to the browser and it started working nicely. I still don't see why this wouldn't work in the server as, at the end of the day I was still passing a simple js object to the .set() method.
Either way, there you have it

Related

RTKQ - Select data without hooks

I'm trying to select cached data from RTKQ without using the auto-generated query hook, but I'm having trouble understanding the docs
const result = api.endpoints.getPosts.select()(state)
const { data, status, error } = result
This is how the docs describe how to access the data, but I can't find any references on how to inject the state object "select()(state)".
I can't figure out how to access the data if I only call the select?
api.endpoints.getPosts.select()
Can someone explain me the difference between "select()" and "select()(state)"
Or what is the optimal solution to access the cached data from RTKQ?
The result of api.endpoints.getPosts.select() is a selector function for the result of using the "getPosts" endpoint without arguments.
Similarly, result of api.endpoints.getPosts.select({ page: 5 }) is a selector function for the result of using the "getPosts" endpoint the argument { page: 5 }.
A selector function is then called as selector(state) or passed into useSelector(selector).
If you write that altogether, you end up with api.endpoints.getPosts.select()(state).
#phry
Thank you for your answer! I'm not 100% sure I understood your answer. But it pointed me in a direction that enabled me to get the data.
I ended up creating a selector like the docs.
export const selectUser = (state) => userApi.endpoints.getUser.select()(state);
and in my function, I referenced it with getting the exported store from configureStore() method
const { data } = selectUser(store.getState());
But I'm not sure if this is the intended way to do it.

FIrebase firestore onSnapshot not firing on change

I am following a simple tutorial on Firebase 9. Everything worked fine until I tried to use onSnapshot method to get the snapshot of changes in db every time the cahnge occurs.
But onSnapshot is not working. I mean it work only for the initial fetch of data, but does not execute the callback function when the change occurs.
I am following a tutorial so my code is identical to the code from the tutorial. My question is whether there is something I need to do in the console to rectify this, some kind of rules or permissions or something.
My code:
const colRef = collection(db, 'books');
const q = query(colRef, where('author', '==', 'patrick rothfuss'));
onSnapshot(q, (snapshot) => {
let books = []
snapshot.docs.forEach(doc => {
books.push({ ...doc.data(), id: doc.id })
})
console.log(books)
})
You can use snapshot.docChanges().forEach method to read and detect changes in data on real time.
I recommend you use this method to modify the array when a change occur.
You can view the code here: https://github.com/firebase/snippets-web/blob/1c4c6834f310bf53a98b3fa3c2e2191396cacd69/snippets/firestore-next/test-firestore/listen_diffs.js#L8-L23
For me, the issue was that I imported collection from the lite version:
import { collection } from "firebase/firestore/lite";
After I changed it
import { collection } from "firebase/firestore";
All is working well. Also, make sure other functions are imported from a normal version.
You can read more about the lite version here:
https://firebase.google.com/docs/firestore/solutions/firestore-lite
You can see it doesn't support snapshot listeners.
Cheers,

How do you store state.Data and state.isValid in ADYEN Card Component?

So I've read the documentation and have followed everything so far. However, in the handleOnChange function, I cannot post the data because it gives the error:
ERROR
Here's how I'm currently trying to post the data, I'm open for any suggestions.
function handleOnChange(state, component) {
state.isValid
state.data
component
if (state.isValid === true) {
this.http.post(environment.paymentFunctionurl + '/', { amount: this.amount, content: state.data}).subscribe((res) => {
console.log(res);
})
}
}
I've tried storing them as variables but it results as undefined. What am I missing here?
Your error is with accessing http, it isn't part of this. You need to make sure http is added to this or likely put http on window so you can access it regardless of your scope.
Side note: your example is passing amount from the client.Do not do this in production!!!!
You might be just doing this while testing, but it's even bad practice in testing. A client may be malicious and change the amount and instead you should use your own backend/database to dictate how much to charge.

Firebase FieldPath.documentId() where query issue

I am trying to query my firebase db using the below code but keep getting docuemtnID is undefined. Is my syntax way off as I keep getting Cannot read property 'documentId' of undefined
db.collection("listings")
.where(db.FieldPath.documentId(), "==", element.drawId)
.get()
.then(docRef => {
});
Firebase is imported as import { db } from "../firebase/init";
You can't access FieldPath as a property of the db instance. Without seeing what's in ../firebase/init, it's not possible to say for sure what you need to use instead (as we can't see how you imported/required the Firestore module). In JavaScript web clients, you would typically say firebase.firestore.FieldValue.
But it's worth noting that since queries using FieldPath.documentId() are only ever going to return a single document with the given ID, you could just get() it instead, and be much more clear and concise:
db.collection("listings").doc(element.drawId).get().then(...)
See: Get a document

Jest Testing with React Native and Contentful

I am trying to test my React Native Application with Jest. I am using Contentful as a CMS to hold my backend information. I am currently trying to test that I am initializing the correct client.
Here is the code I used to initialize the client:
var client = contentful.createClient({
space: 'w20789877', // whatever the space id is
accessToken: '883829200101001047474747737' // some accessToken
})
Here is the code I used to test initializing the client:
describe ('should initialize the correct client', () => {(
it('should initialize the correct client info from contentful', () =>{
expect(client).toEqual('w20789877', '883829200101001047474747737')
});
)};
However, I am getting an error message stating that:
Difference: Comparing two different types of values. Expected undefined but received string.
For some reason I am receiving undefined for the space and accessToken but I correctly initialize the client, as I am able to use the space later on. Even when trying to print out the space and accessToken an undefined value prints.
These are several issues here:
The toEqual matcher receives a single value parameter; you're sending 2
parameters, so effectively only the first one is being used.
The client in this case is a function and you're trying to compare it to a string. Regardless of the fact that the client is not a string, in your case it's also undefined, hence the message "Expected undefined but received string". You are not testing the space or accessToken here, you are testing the client.
I'm not completely sure what you're trying to test here, but this is not specifically related to Contentful.
I'm assuming that the client initialization part is somewhere in the code which you want to unit-test (and not initialized in the test file). I suggest a test that checks that the createClient function of the contentful is being called with your expected parameters when your code is executed; there's no need to test that the client is created - that's Contentful's responsibility to make sure they return a valid client object. What's important is that you pass the correct "space" and "accessToken" parameters required for your app.
Generally speaking, external services should be mocked, and you should only test your own logic and interaction with the external services.
Example
To make it simple, lets say that the code that initializes your client looks like this:
//client.js
var contentful = require('contentful')
export default function initializeClient() {
var client = contentful.createClient({
space: 'w20789877', // whatever the space id is
accessToken: '883829200101001047474747737' // some accessToken
});
}
The test might look something like this:
//client.test.js
describe('contentful client', () => {
let contentful;
let initializeClient;
beforeEach(() => {
jest.mock('contentful');
contentful = require('contentful');
initializeClient = require('./client').default;
});
it('should initialize the contentful client with the correct params', async () => {
initializeClient();
expect(contentful.createClient).toHaveBeenCalledWith({
space: 'w20789877',
accessToken: '883829200101001047474747737'
});
});
});
Note: I didn't actually run or test the above code, but this is the general concept.

Categories

Resources