React Native Firebase Database doesnt return value - reactjs

I am simply trying to just print out the object that should be returning from my firebase DB call but instead, it by-passes the once method and jumps straight to the catch method. I posted the code below.
const db = firebase.database();
var info = db
.ref('/customers')
.once('value')
.then(snapshot => {
console.log('User data: ', snapshot.val());
})
.catch(console.error());

i resolved this mistake....nothing was actually wrong with the code its just that the device i was using was not connected to wi-fi so I am assuming it couldn't actually reach the Firebase servers. Silly mistake.

Related

Firebase data deleted upon page refresh in React

I have been stumped on a work around for this problem for a while now and was hoping someone could help.
I am currently working on a React UI that sends info to the backend Firebase for a budgeting app.
When the page first loads, I pull in the data using this:
const [incomeSources, setIncomeSources] = React.useState([]);
/////////////////////////////////
// PULL IN DATA FROM FIREBASE //
///////////////////////////////
async function getData() {
const doc = await getDoc(userCollectionRef);
const incomesData = doc.data().incomeSources;
// const expensesData = doc.data().expenses;
// const savingsData = doc.data().savingsAllocation;
// SET STATES //
if (incomesData.length > 0) {
setIncomeSources(incomesData);
}
}
then when I want to add a new object to the state array I use a input and button. The issue I currently have is that I have it set up like this:
async function updateFirebaseDocs(userID, stateName, state) {
const userRef = doc(db, "users", userID);
try {
await setDoc(userRef, { [stateName]: state }, { merge: true });
} catch (err) {
console.error("error adding document", err);
}
}
React.useEffect(() => {
updateFirebaseDocs(userID, 'incomeSources', incomeSources)
},[incomeSources])
this works so long as I don't refresh the page, because upon page refresh, incomeSources defaults back to an empty array on render. Causing firebase docs to become an empty array again which deletes firestore data.
I can't for the life of me figure out the workaround even though I know its probably right in front of me. Can someone point me in the right direction please.
Brief summary: I am able to pull in data from backend and display it, but I need a way to keep the backend database up to date with changes made in the Frontend. And upon refreshing the page, I need the data to persist so that the backend doesn't get reset.
Please advise if more information is needed. First time posting.
I have tried using the above method using useEffects dependency, I have also tried using localstorage to work around this but also don't can't think of a way of implementing it. I feel I am tiptoeing around the solution.

MongoDB Realm Functions on React Native

Just started using the Realm MongoDB and i watched this video https://www.youtube.com/watch?v=Evp3xTzWCu4 from MongoDB and followed exactly what he did, but for some the function on the client side is not working. I'm using Expo React Native
I have this simple Realm function
exports = function(arg){
var collection = context.services.get("mongodb-atlas").db("questiondb").collection("questions");
collection.insertOne({name:arg}).then((doc) => {
console.log('Success')
}).catch(error=>console.log(error))
};
When i call it in the real console, it works fine.
This is the front end function
const connectDB = async () => {
const appID = "myapp-ckwfl";
const app = new Realm.App({ id: appID });
const credentials = Realm.Credentials.anonymous();
try {
const user = await app.logIn(credentials);
await user.functions.addQuestion("Myself");
console.log("Logged in");
} catch (error) {
console.log(error);
}
};
I'm getting the 'Logged in' in the console.
I went to check the activity log on the MongoDB atlas and it shows OK to both login and function
However, the function log shows me this message
[ "FunctionError: can't find a table mapping for namespace questiondb.questions" ] { "name": "addQuestion" }
And i have the database 'questiondb' with the collection 'questions'.
What am i missing here?
I ran into a similar error. The problem was that my BSON did not contain an "_id" field. But the BSON validation when saving it allowed me to save the schema like that. But when querying data through graphql I got this exact same error. So the solution was to fix the BSON schema. Even if the BSON schema saves and deploys successfully it can still be that it will not work for graphql.
You can see if your BSON has errors by navigating here:

Hive database not working offline while works fine when connected to internet

I am developing a flutter application in which I am implementing hive database for caching data.
I have added both hive and hive_flutter packages.
I am getting data from APIs and store that to hive to update data, It works fine when I used app connected to internet but didn't works when I try to read while being offline. Here is the code of my API method I am calling to get data:
static Future<List<UserPost>> getPosts() async {
//I call my API in try block, if its successful, I update the data in hive
List<UserPost> posts = [];
Hive.openBox(Constants.APIDATA_BOX);
try {
var response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'),);
if (response.statusCode == 200) {
//Clear hive box from old data
Hive.box(Constants.APIDATA_BOX).clear();
Hive.box(Constants.APIDATA_BOX).put(Constants.API_DATA,jsonDecode(response.body));
}
} catch (e) {
print('You are not connected to internet');
}
//I am getting data here from hive database and it works fine while connected to internet
var listMaps =await Hive.box(Constants.APIDATA_BOX).get(Constants.API_DATA, defaultValue: []);
posts = listMaps.map<UserPost>((map) {
//Here flow stucked whenever working offline,
//Data is also available but here conversion cause error, I have tried many way but fails.
return UserPost.fromMap(map);
}).toList();
return posts;
}
I don't why I am getting error, I have tried many conversion ways here but all works while being online. Any help will be highly apprerciated.
I think I've understood the error but you should explain better which type of error you're having.
Anyway pay attention to the operations on Hive, which are often async, for example Hive.openBox(Constants.APIDATA_BOX);.
So when you have internet connection, you have to await for the response and Hive has time to open the box, otherwise it will throw an error so, considering the futures, you should do this:
static Future<List<UserPost>> getPosts() async {
List<UserPost> posts = [];
await Hive.openBox(Constants.APIDATA_BOX);
try {
var response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'),);
if (response.statusCode == 200) {
//Clear hive box from old data
await Hive.box(Constants.APIDATA_BOX).clear();
await Hive.box(Constants.APIDATA_BOX).put(Constants.API_DATA,jsonDecode(response.body));
}
} catch (e) {
print('You are not connected to internet');
}
var listMaps = await Hive.box(Constants.APIDATA_BOX).get(Constants.API_DATA, defaultValue: []);
posts = listMaps.map<UserPost>((map) {
return UserPost.fromMap(map);
}).toList();
return posts;
}
Note that await Hive.put() in a normal box is not strictly necessary, as explained in the docs

MongoDB Webhook function to save forminput in database

I've been trying to save data from my form in my MongoDB for some time.
I also get a response from the database.
See also: create object in mongo db api onclick sending form
Unfortunately there are not enough tutorials in my mother tongue and I don't seem to understand everything in English.
I've tried some of the documentation, but I always fail.
What is missing in my webhook function so that the form data can be stored?
exports = function(payload) {
const mongodb = context.services.get("mongodb-atlas");
const mycollection = mongodb.db("created_notifications").collection("dpvn_collection");
return mycollection.find({}).limit(10).toArray();
};
The Webhookfunction was totally wrong.
READ THE DOCUMENTATION FIRST
exports = function(payload, response) {
const mongodb = context.services.get("mongodb-atlas");
const requestLogs = mongodb.db("created_notifications").collection("dpvn_collection");
requestLogs.insertOne({
body: EJSON.parse(payload.body.text()),
query: payload.query
}).then(result => {
})
};

Confirm remote sync - Firebase Realtime Database w/ ReactJS+Redux+Saga

I have a ReactJS/Redux/Saga app which currently sends and reads data from a Firebase Realtime Database. As data is sent and received, there's a global redux state value loading, which toggles between true and false between sending data and confirming that data is now in Firebase. loading defaults to false for this case.
When a user updates their data, the flow is currently:
Redux reducer SEND_TO_FIREBASE
return { ...state, loading: true };
This reducer triggers a Saga function sendToFirebaseSaga()
function* syncToFirebaseSaga({ payload: userData }) {
try {
var uid = firebase.auth().currentUser.uid;
const database = (path, payload) => {
firebase
.database()
.ref(path)
.set(payload);
};
yield call(database, "users/" + uid + "/userData", userData);
yield console.log("successfully written to database");
} catch (error) {
alert(error);
}
}
So, at this point loading:true (confirmed that this works)
Then, as a part of componentDidMount of one of my root components, I have a listener for changes to the Firebase Database:
var props = this.props
function updateStateData(payload, props) {
props.syncFirebaseToState(payload);
}
function syncWithFirebase(uid, props) {
var syncStateWithFirebaseListener = firebase.database().ref("users/" + uid + "/userData");
syncStateWithFirebaseListener.on("value", function(snapshot) {
var localState = snapshot.val();
updateStateData(localState, props);
});
}
and this.props.syncFirebaseToState(payload) is a Redux action with this reducer:
return { ...state, data: action.payload, loading: false };
which then confirms that the data has been written to the Firebase Realtime Database, and then takes down the loading page, letting the user know that their update is now safe.
For most cases, this flow works fine. However, I run into problems when the user has a bad internet connection or if I refresh the page too fast. For example:
User loads app.
Disconnects from internet.
Submits data.
Full loop works immediately and loading:false (Firebase Realtime Database wrote it in 'offline mode' and is waiting to be reconnected to the internet)
User reconnects online.
Once online, user immediately refreshes the page (reloading the React app)
Firebase Realtime Database didn't have time to sync the queued updates to the remote database, and now after page refresh, the edits don't make it.
Sometimes, the user doesn't have to lose their internet connection. If they submit an edit (the page instantly returns a 'successful read') and then refresh before the remote server writes it down, the data is loss after the refresh is complete.
Anyway, as you can see, this is a really bad user experience. I really need a way to confirm that the data has actually been written to Firebase before removing the loading screen. I feel like I must be doing something wrong here and somehow getting a successful callback when it isn't.
This is my first time using React/Redux/Saga/Firebase, so I appreciate the patience and the help!
You could just disable offline mode.
I am assuming you don't want to do that so the next thing is to add a condition to check if your update is coming from the cache or the database.
Firebase Realtime Database provides a special location at /.info/connected which is updated every time the Firebase Realtime Database client's connection state changes. Here is an example:
var connectedRef = firebase.database().ref(".info/connected");
connectedRef.on("value", function(snap) {
if (snap.val() === true) {
alert("connected");
} else {
alert("not connected");
}
});
You can then run this check alongside your update to turn to load off and then propagate the change depending on whether it's coming from cache or the actual database.

Resources