how to write firebase v8 code using firebase v9 - javascript

This code block is written in Firebase v8 syntax but how to write this code using firebase v9?

You need to check the Firebase documentation for the upgrade to V9, and you need update your library react-firebase-hooks to 4.0.0 version (here documentation).
In your example, it would look like this:
import { useCollection } from 'react-firebase-hooks/firestore'
import { getFirestore, collection, query, where } from 'firebase/firestore'
const db = getFirestore(firebaseApp);
const q = query(collection(db, 'chats'), where('users', 'array-contains', user.email));
const [value, loading, error] = useCollection(
q,
{ snapshotListenOptions: { includeMetadataChanges: true } }
)

Related

Cloud Firestore subcollection syntax in Web version 9 API

I'm trying to learn Firestore Cloud 9 using a tutorial written for Web version 8. I am stuck trying to refactor what appears to be a subcollection of some sort.
The Web 8 code looks like this:
const ref = firestore.collection('users').doc(auth.currentUser.uid).collection('posts');
const query = ref.orderBy('createdAt');
const [querySnapshot] = useCollection(query);
My (failed) attempt looks something like this:
import { firestore, auth, serverTimestamp } from "#/lib/firebase";
import { collection, getDocs, orderBy, query } from "firebase/firestore";
import { useRouter } from "next/router";
import { useCollection } from "react-firebase-hooks/firestore";
const ref = collection(firestore, 'users');
const q = query(
ref,
where('username', '==', auth.currentUser.uid),
orderBy('createdAt', 'desc')
);
//const newPosts = (await getDocs(q)).docs.map((doc) => doc.data());
const [querySnapshot] = useCollection(q);
I can get the first collection without issue. However grabbing the subcollection (?) via the doc(ument) isn't something I can figure out. I've tried getDocs() (commented out, above) as well as getDoc() & .doc.
This line in the v8 and before syntax:
const ref = firestore.collection('users').doc(auth.currentUser.uid).collection('posts');
Will look like this in v9 and later:
const ref = collection(firestore, 'users', auth.currentUser.uid, 'posts');

Why error Expected first argument to collection() to be a CollectionReference

I am getting the following error when trying to get all documents from a collection in Firestore using firebase admin SDK:
[nuxt] [request error] Expected first argument to collection() to be a
CollectionReference, a DocumentReference or FirebaseFirestore
I am testing via a simple console.log:
/server/api/posts.js:
import { firestore } from '../utils/firebase'
import { collection, getDocs } from 'firebase/firestore'
export default defineEventHandler(async (event) => {
const colRef = collection(firestore, 'posts')
console.log(colRef)
})
Here is how I am initializing firestore:
/server/utils/firebase.js:
import { initializeApp, cert } from 'firebase-admin/app'
import { getFirestore } from 'firebase-admin/firestore'
import serviceAccount from '../../service-account.json'
export const app = initializeApp({
credential: cert(serviceAccount)
})
export const firestore = getFirestore()
Note: The following code works on the server-side and I am able to get a document back, but for some reason I can't use the collection() like in the above example.
import { firestore } from '../utils/firebase'
export default defineEventHandler(async (event) => {
const ref = firestore.doc(`animals/dog`)
const snapshot = await ref.get()
const data = snapshot.data()
console.log(data)
// return {
// data
// }
})
Also, if I run the collection() function on the client side, I can successfully retrieve the posts. I just can't figure out why it won't work server-side.
Anyone know why I get the above error?
None of the server code you have shared align to such an error message. The error indicates that you are calling .get() or .onSnapshot() with something that is not a DocumentReference or a CollectionReference.
Note: collection() and doc() are functions that return References. They don't actually communicate to the FS service...a Reference is (essentially) a string such as `/posts' or '/posts/1234567'
So, somewhere in your code, you need to find where it is hitting the above error and either share it here or understand why what you are calling it on is not a valid CollectionReference or DocumentReference.

Firebase realtime db limitToFirst(10) doesnt working

i am facing issue i am trying to get only 10 data from firebase but how can i achieve that if ref(database, "messages/").limitToFirst(10) is throwing:
ref(...).limitToFirst is not a function
My code:
const newMsg = ref(database, 'messages/').limitToFirst(10);
onChildAdded(newMsg, (data) => {
if(data.val().name != name){
var divData = '<div class="message"><div class="others">'+data.val().name+': </div><div>'+data.val().message+'</div></div>';
//oponent message
$("#chat-history").append(divData);
}else{
var divData = '<div class="message"><div class="user">'+data.val().name+': </div><div>'+data.val().message+'</div></div>';
//sent message
$("#chat-history").append(divData);
}
});
Where database is
const app = initializeApp(firebaseConfig);
const database = getDatabase(app);
And my imports look like this:
import {initializeApp} from "https://www.gstatic.com/firebasejs/9.6.6/firebase-app.js";
import {
getDatabase,
set,
ref,
push,
child,
onValue,
onChildAdded
} from "https://www.gstatic.com/firebasejs/9.6.6/firebase-database.js";
EDIT:
After a hour i see where is the problem in my import i need to add query, limitToLast
import {
getDatabase,
set,
ref,
query,
push,
child,
onValue,
onChildAdded,
limitToLast
} from "https://www.gstatic.com/firebasejs/9.6.6/firebase-database.js";
And in my function just call it like this:
const newMsg = query(ref(database, 'messages/'), limitToLast(10));
onChildAdded(newMsg, (data) => {
In the new Modular SDK (v9.0.0+), you can build a Query using query() function (instead of chaining the QueryConstraints):
import { ref, query, limitToFirst } from "firebase/database"
const newMsg = query(ref(database, 'messages/'), limitToFirst(10))
onChildAdded(newMsg, (data) => {
// ...
})
The new SDK uses a functional syntax unlike the older name-spaced one so limitToFirst is a top-level function now as in above code snippet.
Also checkout:
How to read, write and query data in Firebase Realtime Database using Firebase SDK v9 (Modular)
Working with lists of data

Reducing Firebase SDK bundle size?

I've used the new tree-shakeable version of Firebase SDK, which still seems to produce quite a large chunk, considering what I use it for.
I only use the Firestore part, and have actually moved all Firestore operations to the backend, the only thing I'm doing on the front end is initiating the Firebase app instance and starting a snapshot listener (due to the real-time ability), yet the bundle produced is still 275kb large.
import { initializeApp } from 'firebase/app'
import { getFirestore, collection, doc, onSnapshot, query, where, orderBy } from 'firebase/firestore'
const documents = ref(null)
const firebaseApp = initializeApp(firebaseConfig)
const db = getFirestore(firebaseApp)
const ref = query(collection(db, 'documents'), where(`something`, '==', 'something'), orderBy('createdAt', 'desc'))
const unsub = onSnapshot(ref, (snap) => {
let results = []
snap.docs.forEach(el => {
el.data().createdAt && results.push({ ...el.data(), id: el.id })
})
documents.value = results
}, err => {
console.log(err.message)
documents.value = null
})
Is there a way to reduce that size slightly, without sacrificing the real-time ability?

Document creation timestamp (server-time) in Firestore

I'm new to firebase and firestore, creating a single-page app, I was wondering how can I store the document creation time with the document, representing the server-side time. When I changed my system time to an incorrect time and then ran the code below, it was storing the same (incorrect) timestamp for both clientDate and serverTimestamp fields.
I tried the following (Firebase JavaScript SDK version 9.0.2):
import { addDoc, collection, Timestamp } from 'firebase/firestore';
import { db } from '../index';
export const storeSomething = async () => {
const data = {
clientDate: new Date(),
serverTimestamp: Timestamp.now(),
};
const someCol = collection(db, 'somecollection');
const docRef = await addDoc(someCol, data);
};
The Timestamp.now() function returns the current client-side time, so is indeed sensitive to clock skew and manipulation.
To write a server-side timestamp, use:
in v9/modular syntax: serverTimestamp()
in v8/compat syntax: firebase.firestore.FieldValue.serverTimestamp()
in the Admin SDK: admin.firestore.FieldValue.serverTimestamp()

Categories