Could not reach Cloud Firestore backend - React native Firebase v9 - javascript

I saw many questions on SO regarding this issue and none of them was answered (or the solution doesn't work), I don't know why. People are having this error continuously but no solution is being provided. And from past few days even I'm encountering this error (Note: It seems to be working fine on my physical device (not while debugging, it works on only if I release it), but not on android emulator, so I'm pretty sure my internet is working fine):
Setting a timer for a long period of time, i.e. multiple minutes, is a performance and correctness issue on Android as it keeps the timer module awake, and timers can only be called when the app is in the foreground. See https://github.com/facebook/react-native/issues/12981 for more info.
(Saw setTimeout with duration 3052257ms)
Authorization status: 1
[2022-02-09T07:05:26.500Z] #firebase/firestore: Firestore (9.6.5): Could not reach Cloud Firestore backend. Backend
didn't respond within 10 seconds.
This typically indicates that your device does not have a healthy Internet connection at the moment. The client will
operate in offline mode until it is able to successfully connect to the backend.
Authorization status: 1
[2022-02-09T07:08:44.688Z] #firebase/firestore: Firestore (9.6.5): Connection WebChannel transport errored: me {
"defaultPrevented": false,
"g": Y {
"A": true,
"J": null,
"R": [Circular],
"g": $d {
"$": true,
"$a": 2,
"A": 3,
"B": null,
"Ba": 12,
"C": 0,
"D": "gsessionid",
"Da": false,
"Ea": Dd {
"g": Cd {},
},
... & so on...
Package.json:
"#react-native-firebase/app": "^14.3.1",
"#react-native-firebase/messaging": "^14.3.1",
"#react-native-google-signin/google-signin": "^7.0.4",
"expo": "~44.0.0",
"firebase": "^9.6.3",
The authentication & messaging seems to be working fine, but I think the db from firestore is having this issue.
Following is some of the code from my firebase.tsx config file:
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
import { getFirestore } from "firebase/firestore";
const firebaseConfig = {
apiKey: "",
authDomain: "",
databaseURL: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: "",
measurementId: "",
};
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const db = getFirestore(app);
export { auth, db };
What I tried so far:
Changing the firestore database rules as mentioned in this answer: https://stackoverflow.com/a/70980383/11685381
Using this workaround: https://github.com/firebase/firebase-js-sdk/issues/5667#issuecomment-952079600
I'm not using any .env variables according to this answer: https://stackoverflow.com/a/69095824/11685381
Wiped android emulator data, then Cold Boot. Didn't work.
Upgraded firebase-9.6.3 to firebase-9.6.6. Didn't work.
cleaned the build folder, yarn installed all the packages again. Didn't work.
Can anyone provide any working solution to this problem?
Thank you!
EDIT-1:
The code where I'm calling firestore db especially:
In my HomeScreen.tsx:
import { doc, setDoc, onSnapshot, collection } from "firebase/firestore";
import { db } from "../../../firebase";
// inside functional component
useEffect(() => {
const addUser = () => {
const path = doc(db, "Users", user.uid);
const data = {
_id: user.uid,
name: user.displayName,
email: user.email,
};
setDoc(path, data)
.then(() => {
console.log("User added to db");
})
.catch((err) => {
console.log("Error while adding user to firestore: ", err);
});
};
addUser();
}, []);
useEffect(() => {
const unsub = onSnapshot(collection(db, "Items"), (snapshot) =>
setItems(snapshot.docs.map((doc) => doc.data()))
);
return () => unsub();
}, []);
// so nothing is being displayed here as firestore is not working.

Found out the solution on my own after a lot of search. Although I had to make a new bare react native project from scratch, and even then I was encountering that error, I had literally lost hope with firebase at that point. Then after sometime I changed my firebase config to the below code and it worked:
import {initializeApp} from 'firebase/app';
import {getAuth} from 'firebase/auth';
import {initializeFirestore} from 'firebase/firestore';
const firebaseConfig = {
apiKey: '',
authDomain: '',
projectId: '',
storageBucket: '',
messagingSenderId: '',
appId: '',
measurementId: '',
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const db = initializeFirestore(app, {
experimentalForceLongPolling: true,
});
export {auth, db};
I had to change the initialization of db as mentioned above, hope it works for everyone out there who's stuck on this weird error.
Thank you all for your help!

First config your db, in firestore.js
import firebase, { initializeApp, getApps, getApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
let app;
if (getApps().length === 0) {
app = initializeApp(firebaseConfig);
} else {
app = getApp();
}
const db = getFirestore(app);
export { db, auth };
Then add collection to the fireStore DB by:
import {db} from "../firebase.js";
import { collection, addDoc } from "firebase/firestore";
const docRef = await addDoc(collection(db, "chats"), {
chatName: input
}).then(() => {
navigation.goBack();
}).catch((error) => alert(error) );
for Reference: https://firebase.google.com/docs/firestore/quickstart

Related

Could not reach Cloud Firestore backend. Connection failed 1 time. this typically indicates that your device does not have healthy Internet

I am connecting javascript & firebase but got this issue,
I am facing this issue I switched networks as well but it doesn't work,
firebase v9
javascript
package file: webpack, webpack-cli
filename: index.js
import { initializeApp } from 'firebase/app';
import {getFirestore, collection, getDocs} from 'firebase/firestore';
const firebaseConfig = {
apiKey: ...,
authDomain: ...,
projectId: ...,
storageBucket: ...,
messagingSenderId: ...,
appId: ...
};
// initialize application
const app = initializeApp(firebaseConfig, {
experimentalForceLongPolling: true,
useFetchStreams: false
});
// initialize serivice
const db = getFirestore();
// collection ref
const colRef = collection(db, 'books');
// get collection data
getDocs(colRef)
.then(snapshot => {
console.log(snapshot.docs)
})
Thanks in advance!
To connect to the firestore applications you need to check that your internet connection is very well,
I encounter that the internet I was working on was not well enough, I changed the connection again and restart the system,
It resolved the issue!

Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore

i have been solving this issue since past 2 days but cant get any idea of how it is solved
const handleSignUp = () => {
auth
.createUserWithEmailAndPassword(email, password)
.then(userCredentials => {
console.log(userCredentials.user.uid)
const user = userCredentials.user;
console.log('Registered with:', user.email);
setDoc(doc(db, "users", "LA"), {
name: "Los Angeles",
// state: "CA",
// country: "USA"
});
})
.catch(error => alert(error.message))
}
The Firebase module is here
if it need any changes of any dependency or any version
please suggest as firebase version is 9.6.11,while firestore is of 3.4.14
// Import the functions you need from the SDKs you need
// import firebase from "firebase";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
import firebase from "firebase/compat/app";
import "firebase/compat/auth";
import "firebase/compat/firestore";
import "firebase/compat/database"
// import { getFirestore } from "#firebase/firestore";
import { getFirestore } from 'firebase/firestore'
// import { getFirestore } from 'firebase/firestore/lite'
const firebaseConfig = {
apiKey: ........................
authDomain: ........................
projectId: ........................
storageBucket: ........................
messagingSenderId: ........................
appId: ........................
};
// Initialize Firebase
let app;
if (firebase.apps.length === 0) {
app = firebase.initializeApp(firebaseConfig);
} else {
app = firebase.app()
}
export const auth = firebase.auth()
// export const db = firebase.firestore();
export const db = getFirestore(app)
The error indicates that you are calling setDoc() function to something that is not a DocumentReference or a CollectionReference.
You may try to get the details from the console log as to which variable reference it is hitting the above error and understand why what you are calling it on is not a valid CollectionReference or DocumentReference. Please read through the helpful documentation for Collection Reference
The function setDoc() ,writes to the document referred to by the specified DocumentReference. If the document does not yet exist, it will be created. If you provide merge or mergeFields, the provided data can be merged into an existing document.The result of this write will only be reflected in document reads that occur after the returned promise resolves. If the client is offline, the write fails. If you would like to see local modifications or buffer writes until the client is online, use the full Firestore SDK.
Also check and verify that you are to call the firebase admin sdk rather than the client SDK and see if that works.
It's an AngularFire version issue, basically if you're using Angular 12, with Firebase 9 you need #angular/fire#^7.0
The compatibility table on the firebase page is key: https://github.com/angular/angularfire#angular-and-firebase-versions
I struggled with this issue for hours ?days? and it was because I had angularfire 7.4 (even 7.2 didn't work).

Can't get data from firebase in react chart

I'm using ApexChartJs for my react project, but when I tried to fetch dynamic data from my firebase database, then show me undefined.
here is my part of code from my project:
import React, { useEffect, useState } from "react";
import Chart from "react-apexcharts";
import { auth, db } from "./firebase";
import { useCollection } from "react-firebase-hooks/firestore";
const [dataPoint, setDataPoint] = useState([]);
const query = db.collection("data");
const [snapshot, loading, error] = useCollection(query);
const [series, setSeries] = useState([]);
useEffect(() => {
setSeries([
{
name: "Desktops",
data: snapshot?.docs.map((doc) => doc.data().value),
},
]);
}, [snapshot]);
console.log(series);
data in the firebase look like:
firebase configure file:
import firebase from "firebase";
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
apiKey: "AIzaSyC2mfjPdIdXxGgJFqqVviw32xoaEMxxxxxx",
authDomain: "chart-app-4591b.firebaseapp.com",
projectId: "chart-app-4591b",
storageBucket: "chart-app-4591b.appspot.com",
messagingSenderId: "995691438244",
appId: "1:995691438244:web:6d945f72ff51d444664631",
measurementId: "G-2B9ZFG6E33",
};
const app = firebase.initializeApp(firebaseConfig);
const db = app.firestore();
const provider = new firebase.auth.GoogleAuthProvider();
const auth = firebase.auth;
export { db, provider, auth };
If your firebase app is well set-up and configured appropriately, the main issue that may lead an undefined query result is that the result are still being loaded.
To overcome this, you should update your series state whenever the loading property changes (along with query result snapshot changes):
const query = db.collection("data");
const [snapshot, loading, error] = useCollection(query);
useEffect(() => {
setSeries([
{
name: "Desktops",
data: snapshot?.docs.map((doc) => doc.data().value),
},
]);
}, [loading, snapshot]);
You should provide alternative error handling as well for state update.
Update (per the permission error)
A common error source would be the lack of privileges to read and write from the configured Firestore DB highlighted by below error message:
FirebaseError: Missing or insufficient permissions
To allow all reads and writes for test only mode (should never be the case for a production system), you can set below Security Rules for the database:
// Allow read/write access to all users under any conditions
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true;
}
}
}
You can read more on Cloud Firestore Security Rules in the official documentation.

Firebase Cloud Messaging foreground notification not working in Vue

I've been working on integrating FCM in my Vue PWA app. So far I've managed to get the background notification working, but handling notifications when the app's on the foreground doesn't work. Here's my code.
src/App.vue
import firebase from './plugins/firebase'
export default {
// Other stuff here...
methods: {
prepareFcm () {
var messaging = firebase.messaging()
messaging.usePublicVapidKey(this.$store.state.fcm.vapidKey)
messaging.getToken().then(async fcmToken => {
this.$store.commit('fcm/setToken', fcmToken)
messaging.onMessage(payload => {
window.alert(payload)
})
}).catch(e => {
this.$store.commit('toast/setError', 'An error occured to push notification.')
})
}
},
mounted () {
this.prepareFcm()
}
}
public/firebase-messaging-sw.js
importScripts('https://www.gstatic.com/firebasejs/5.5.6/firebase-app.js')
importScripts('https://www.gstatic.com/firebasejs/5.5.6/firebase-messaging.js')
firebase.initializeApp({
messagingSenderId: '123456789'
})
const messaging = firebase.messaging()
messaging.setBackgroundMessageHandler(function (payload) {
return self.registration.showNotification(payload)
})
src/plugins/firebase.js
import firebase from '#firebase/app'
import '#firebase/messaging'
// import other firebase stuff...
const firebaseConfig = {
apiKey: '...',
authDomain: '...',
databaseURL: '...',
projectId: '...',
storageBucket: '...',
messagingSenderId: '123456789',
appId: '...'
}
firebase.initializeApp(firebaseConfig)
export default firebase
What did I do wrong?
I've found a solution in another QA here in StackOverflow (which I can't find anymore for some reason).
Turns out you have to use Firebase API v7.8.0 instead of 5.5.6 like the docs said at the time. So those first two lines in public/firebase-messaging-sw.js should read like this instead:
importScripts('https://www.gstatic.com/firebasejs/7.8.0/firebase-app.js')
importScripts('https://www.gstatic.com/firebasejs/7.8.0/firebase-messaging.js')
Same issue i was faced. In my case firebase version in "package.json" and "firebase-messaging-sw.js" importScripts version was different. After set same version in "firebase-messaging-sw.js" importScripts which was in
"package.json", my issue is resolved.
Before change
**"package.json"**
"firebase": "^8.2.1",
**"firebase-messaging-sw.js"**
importScripts('https://www.gstatic.com/firebasejs/7.8.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/7.8.0/firebase-messaging.js');
After change
**"package.json"**
"firebase": "^8.2.1",
**"firebase-messaging-sw.js"**
importScripts('https://www.gstatic.com/firebasejs/8.2.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/8.2.1/firebase-messaging.js');
In my case the version on package.json (8.2.1) was different from the actual SDK_VERSION (8.0.1)
After changed service-workers with the same version worked..
I had a bunch of issues setting firebase push notifications for Vue 3 (with Vite), and I had PWA support enabled with vite-plugin-pwa, so it felt like I was flying blind half the time. I was finally able to set up support for PWA, but then I ran into the following issues:
I was getting notifications in the background (when my app was not in focus), but not in the foreground.
When I did get notifications in the background, it appeared twice.
Here's my complete setup. I have the latest firebase as of this post (9.12.1)
// firebase-messaging-sw.js file in the public folder
importScripts(
"https://www.gstatic.com/firebasejs/9.12.1/firebase-app-compat.js"
);
importScripts(
"https://www.gstatic.com/firebasejs/9.12.1/firebase-messaging-compat.js"
);
// Initialize Firebase
firebase.initializeApp({
apiKey: "",
authDomain: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: "",
measurementId: "",
});
const messaging = firebase.messaging();
messaging.onBackgroundMessage(function (payload) {
// Customize notification here
const notificationTitle = payload.notification.title;
const notificationOptions = {
body: payload.notification.body,
icon: "/icon.png",
};
self.registration.showNotification(notificationTitle, notificationOptions);
});
I've seen some posts online provide the onBackgroundMessage here in the service worker, but I experimented with commenting it out and it seemed to fix the issue of notifications appearing twice.
Next, is a firebase.js file with which I retrieve tokens and subsequently listen for foreground notifications.
// firebase.js in same location with main.js
import firebase from "firebase/compat/app";
import { getMessaging } from "firebase/messaging";
const firebaseConfig = {
apiKey: "",
authDomain: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: "",
measurementId: "",
};
const app = firebase.initializeApp(firebaseConfig);
export default getMessaging(app);
And then in main.js
import App from "./App.vue";
import firebaseMessaging from "./firebase";
const app = createApp(App)
app.config.globalProperties.$messaging = firebaseMessaging; //register as a global property
And finally, in App.vue (or wherever you wish to get tokens and send to your serverside)...
import {getToken, onMessage} from "firebase/messaging";
export default {
mounted() {
getToken(this.$messaging, {
vapidKey:
"XXX-XXX",
})
.then((currentToken) => {
if (currentToken) {
console.log("client token", currentToken);
onMessage(this.$messaging, (payload) => {
console.log("Message received. ", payload);
});
//send token to server-side
} else {
console.log(
"No registration token available. Request permission to generate one"
);
}
})
.catch((err) => {
console.log("An error occurred while retrieving token.", err);
});
}
}
Of course don't forget the vapidKey. Took a minute, but it worked perfectly.
For now, I am not offering any opinion as to what the foreground notification should look like, so I am merely logging the payload. But feel free to show it however you deem fit.

How to enable offline data in firestore for web

I want to enable offline data in my project.
I found the right code for this but I don't know where to implement the code
I implement the code inside the firebaseConfig.js file:
import firebase from 'firebase'
import 'firebase/firestore'
// firebase init
// init code goes here
var config = {
apiKey: '',
authDomain: '',
databaseURL: '',
projectId: '',
storageBucket: '',
messagingSenderId: ''
}
firebase.initializeApp(config)
firebase.firestore().enablePersistence()
.then(function () {
// Initialize Cloud Firestore through firebase
var db = firebase.firestore();
})
.catch(function (err) {
console.log(err)
})
// firebase utils
const db = firebase.firestore()
const oldRealTimeDb = firebase.database()
const auth = firebase.auth()
const currentUser = auth.currentUser
// date issue fix according to firebase
const settings = {
timestampsInSnapshots: true
}
db.settings(settings)
// firebase collections
const usersCollection = db.collection('users')
const postsCollection = db.collection('posts')
export {
db,
auth,
currentUser,
postsCollection,
usersCollection
}
main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import {store} from './store'
import './registerServiceWorker'
import Vuetify from 'vuetify'
import 'vuetify/dist/vuetify.min.css' // Ensure you are using css-loader
const fb = require('./firebaseConfig.js')
Vue.config.productionTip = false
export const bus = new Vue()
Vue.use(Vuetify)
let app
fb.auth.onAuthStateChanged(user => {
if (!app) {
app = new Vue({
el: '#app',
store,
router,
template: '<App/>',
components: {
App
},
render: h => h(App)
}).$mount('#app')
}
})
I got this error:
The sample code provided in the documentation suggests that you should call enablePersistence() and possibly make note if it fails for some given reason:
firebase.initializeApp({
apiKey: '### FIREBASE API KEY ###',
authDomain: '### FIREBASE AUTH DOMAIN ###',
projectId: '### CLOUD FIRESTORE PROJECT ID ###',
});
firebase.firestore().enablePersistence()
.catch(function(err) {
if (err.code == 'failed-precondition') {
// Multiple tabs open, persistence can only be enabled
// in one tab at a a time.
// ...
} else if (err.code == 'unimplemented') {
// The current browser does not support all of the
// features required to enable persistence
// ...
}
});
Subsequent queries after calling enablePersistence() will be internally queued until it fully completes, which means that the query may or may not be using locally cached data, depending on the result of enablePersistence(). If it's important to your app to be able to use local persistence, you may wish to wait on its result (triggering on the returned promise) before performing the query.
Just remove the second firebase.firestore() and call the enablePersistence as follows:
import firebase from 'firebase'
import 'firebase/firestore'
// firebase init
// init code goes here
var config = {
apiKey: '',
authDomain: '',
databaseURL: '',
projectId: '',
storageBucket: '',
messagingSenderId: ''
}
firebase.initializeApp(config)
const db = firebase.firestore();
const auth = firebase.auth();
const currentUser = auth.currentUser;
// date issue fix according to firebase
const settings = {
timestampsInSnapshots: true
};
db.settings(settings);
db.enablePersistence();
// firebase utils
//const db = firebase.firestore() // <---- Remove this line
const oldRealTimeDb = firebase.database()
const auth = firebase.auth()
const currentUser = auth.currentUser

Categories