Can't fetch Firbase webapp database in reactjs - reactjs

I can't fetch the data from firebase database.I have used these code to import the firebase database below:
import firebase from 'firebase/app'
import "firebase/database";
const firebaseDB = firebase.database();
const firebaseArticle = firebaseDB.ref('articles')
const firebaseTeams = firebaseDB.ref('teams')
const firebaseVideos = firebaseDB.ref('videos')
And in another file where I want to fetch the data from firebase i used these codes
UNSAFE_componentWillMount() {
firebaseArticle
.limitToFirst(3)
.once("value")
.then((snapshot) => {
const news = [];
snapshot.forEach((childSnapshot) => {
news.push({
...childSnapshot.val(),
id: childSnapshot.key,
});
});
this.setState({
news
});
});
I am getting these error messages in the console. Looks like I've got problems in lifecycles even though I've used UNSAFE_lifecyclename which they recommended. What should I do now to fetch data from firebase? & How can I get rid of these warnings?
Thanks

You should use componentDidMount, like so:
componentDidMount() {
firebaseArticle
.limitToFirst(3)
.once("value")
.then((snapshot) => {
const news = [];
snapshot.forEach((childSnapshot) => {
news.push({
...childSnapshot.val(),
id: childSnapshot.key,
});
});
this.setState({
news
});
});
}

Related

react next Js create JSON url

i want to use grafana platform that display data
i need to create route patch that contain the data as json and use is on grafana
on react i can do it with app.get request and send it res.json()
but with next js it wont work as it should be
adding code
*** i am in the middle of project so all this request/database configuration work
so there is no problem with kind of configuration
i just want when i go to the correct url i could get the users json and use this url something like in the picture that i upload
import user from "../../models/userModel";
import mongoose from "mongoose";
const handler = async(req, res) => {
await mongoose.connect(
database url that i deleted
);
const fetchAllUser = async () => {
const users = await user.find();
res.json(users);
};
if( req.method === "GET"){
fetchAllUser();
}
};
export default handler;
//send request to get all the users from the db and i get it!
const allUsers = async()=>{
const users = await axios.get(`${herokuUrl}user4`)
return users.data
}
// users components that run on the routes of "users"
import React, { useEffect } from "react";
import { useDataProvider } from "../context/Data";
const Users = () => {
const { allUsers } = useDataProvider();
useEffect(() => {
allUsers();
}, []);
return <></>;
};
export default Users;

How to push the data to firestore after stripe checkout session complete using React js frontend

I am trying to push the checkout basket data to firebase firestore after a stripe checkout session complete using react js node js. the checkout session successfully completed without error. However, there are NO user orders data being push to firebase firestore from the piece of code below:
const { error } = await stripe.redirectToCheckout({
sessionId
}).then(()=>{
db
.collection('users')
.doc(user?.uid)
.collection('orders')
.doc()
.set({
basket: basket,
// amount: paymentIntent.amount,
})
});
Below is the whole pieces of codes of backend and frontend
Functions/index.js
const functions = require("firebase-functions");
const express=require("express");
const cors=require("cors");
require('dotenv').config({ path: './.env' });
//API
const stripe=require("stripe")('sk_test_51KM...zIP');
//App config
const app=express();
var admin = require("firebase-admin");
var serviceAccount = require("./serviceAccountKey.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
//middlewares
app.use(cors({origin: true}));
app.use(express.json());
async function createCheckoutSession(req, res) {
const domainUrl = process.env.WEB_APP_URL;
const { line_items, customer_email } = req.body;
// check req body has line items and email
if (!line_items || !customer_email) {
return res.status(400).json({ error: 'missing required session parameters' });
}
let session;
try {
session = await stripe.checkout.sessions.create({
payment_method_types: ['card'],
mode: 'payment',
line_items,
customer_email,
success_url: `${domainUrl}/success?session_id={CHECKOUT_SESSION_ID}`,
// success_url: '/success?session_id={CHECKOUT_SESSION_ID}',
cancel_url: `${domainUrl}/canceled`,
shipping_address_collection: { allowed_countries: ['GB', 'US'] }
});
res.status(200).json({ sessionId: session.id, });
} catch (error) {
console.log(error);
res.status(400).json({ error: 'an error occured, unable to create session'});
}}
app.get('/',(req, res)=>res.send('Hello World!'));
app.post('/create-checkout-session', createCheckoutSession);
exports.api=functions.https.onRequest(app);
src/strip-checkout.js
import React, { useContext, useState,useEffect } from 'react';
import { useStripe } from '#stripe/react-stripe-js';
import CheckoutProduct from '../CheckoutProduct';
import { useStateValue } from '../StateProvider';
import { db } from '../firebase';
import { fetchFromAPI } from '../helpers';
import "./stripe-checkout.css";
import { useHistory } from 'react-router-dom/cjs/react-router-dom.min';
const StripeCheckout = () => {
const history=useHistory();
const [{basket, user},dispatch]=useStateValue();
const [email, setEmail] = useState('');
const [processing,setProcessing]=useState("");
const stripe = useStripe();
const handleGuestCheckout = async (e) => {
e.preventDefault();
setProcessing(true);
const line_items = basket?.map(item => {
return {
quantity: 1,
price_data: {
currency: 'usd',
unit_amount: item.price*100, // amount is in cents
product_data: {
name: item.title,
description: item.material
images: [item.image[0]],
}}}})
const response = await fetchFromAPI('create-checkout-session', {
body: { line_items, customer_email: user.email },
})
const { sessionId } = response;
const { error } = await stripe.redirectToCheckout({
sessionId
}).then(()=>{
db
.collection('users')
.doc(user?.uid)
.collection('orders')
.doc()
.set({
basket: basket,
})
});
console.log(sessionId);
if (error) {
console.log(error);
}}
return (
<form onSubmit={handleGuestCheckout}>
<div className='submit-btn'>
<button type='submit' >
<span>{processing ?<p>Processing</p>:
"Proceed to Checkout"}</span>
</button>
</div>
</form>
);
}
export default StripeCheckout;
Since there is no shown any error or warning, how to push the data to firestore after stripe checkout session complete in this case?
Stripe Checkout returns to either a success- or a cancel-URL.
It does not send data to both URLs, except the CHECKOUT_SESSION_ID you may add to it when defining these URLs.
The usual way to get data from Stripe Checkout is to use a Firebase Function Webhook. This Webhook is called by Stripe if a transactions is done, or upon failure etc. This Webhook stores the data in Firebase. I had the same problem and found no other, proper solution than using a Webhook.
https://stripe.com/docs/webhooks
There is also a Firebase Extension providing support for Stripe, including the Webhook. Basically. it will add some collections to Firestore, which you then can query.
https://firebase.google.com/products/extensions/stripe-firestore-stripe-payments

How Can I exist Queries When the User refresh the browser in react-query?

When refresh the Browser, inactive state queries have gone.
How Can I maintain queries When I refresh the Browser?
and also, I want to maintain userData when the pages go out
code like this.. (with zustand, react-query)
const {userId} = useParams();
const userData = useStore((state) => state.userData);
const {isLoading, data} = useQuery('user', () => getUser(userId), {
onSuccess: (res) => {
useStore.setState({userData: res.data});
},
onError: (err) => errorMsg(err),
});
getUser func
export const getUser = (userId)=>{
if(!userId) return;
return axios.get(`${API.user(userId)}`};
}
React Query provides experimental (as of June 2022) support for storing data in Local Storage:
import { persistQueryClient } from 'react-query/persistQueryClient-experimental'
import { createWebStoragePersistor } from 'react-query/createWebStoragePersistor-experimental'
// probably also supports session storage as the API is the same
const localStoragePersistor = createWebStoragePersistor({storage: window.localStorage})
// the queryClient you pass to QueryClientProvider
persistQueryClient({
queryClient,
persistor: localStoragePersistor,
})
Source: https://react-query.tanstack.com/plugins/persistQueryClient

React native problem saving data to firestore

Here is my code.
import FirebaseKeys from "./config";
import firebase from 'firebase/app';
class Fire {
constructor() {
firebase.initializeApp(FirebaseKeys);
}
addPost = async ({text, localUri}) => {
const remoteUri = await this.uploadPhotoAsync(localUri)
return new Promise((res, rej) => {
this.firestore.collection("posts").add({
text,
uid: this.uid,
timestamp: this.timestamp,
image: remoteUri
})
.then(ref => {
res(ref)
})
.catch(error => {
rej(error)
});
});
};
uploadPhotoAsync = async uri => {
const path = `photos/${this.uid}/${Date.now()}.jpg`
return new Promise(async (res, rej) => {
const response = await fetch(uri)
const file = await response.blob()
let upload = firebase.storage().ref(path).put(file)
upload.on(
"state_changed",
snapshot => {},
err => {
rej(err)
},
async () => {
const url = await upload.snapshot.ref.getDownloadURL();
res(url);
}
);
});
};
What I have noticed is there is no problem uploading image on uploadImageAsync but when it comes to addPost method it does not create a collection named "post".
what should I do with this? thankyou in advance. btw I am not using expo on this.
First of all, the collection that your addPost method is trying to create is called "posts", not "post". When it comes to Firestore, always check that your security rules allow for this user to write to that path.
It would also be nice to see the usage of addPost, and see what its res and rej return.

Firestore: enablePersistence() and then using redux with offline database?

So, essentially, I'm using Create-React-App and I want to allow users to add data to redux either offline or online. I also want to sync redux with Firestore.
In my main attempt, I initialize my firebase settings:
// ./firebase/firebase.js
var firestoreDatabase;
firebase.initializeApp(config.firebase.config);
firebase.firestore().enablePersistence().then(() => {
firestoreDatabase = firebase.firestore();
});
export { firebase, firestoreDatabase };
Then, to make sure this has fired properly (this is definitely wrong, but I can't figure out the best place to catch the enablePersistence() return... ):
// src/index.js
import { firebase, firestoreDatabase } from "./firebase/firebase";
firebase.auth().onAuthStateChanged(user => {
store.dispatch(setReduxData()).then(() => {
if (firestoreDatabase) {
ReactDOM.render(application, document.getElementById("root"));
}
});
});
ACTIONS FILE
import { firestoreDatabase } from "../firebase/firebase";
export const setReduxData = () => {
return (dispatch, getState) => {
const uid = getState().auth.uid;
const data = { newData: '123' };
return firestoreDatabase
.collection("Users")
.doc(uid)
.collection("data")
.add(data)
.then(ref => {
// so, this never gets fired
dispatch(
addData({
id: ref.id,
...data
})
);
})
So the dispatch never gets fired, however, when I refresh the application, the data I entered { newData: '123' } is added to the store.
I think my entire way of handling this is wrong. I don't like exporting firestoreDatabase as undefined and then updating it when enablePersistence() returns...
I would like to just enablePersistence() once and then use the cache or the server depending on if the user is online or not... Redux should operate the same regardless...
Any thoughts and feedback are welcome!
So, I figured out how to load Firestore properly in my application:
In my firebase.js file:
import * as firebase from "firebase";
import config from "../config";
// https://firebase.google.com/docs/reference/js/
firebase.initializeApp(config.firebase.config);
const database = firebase.database();
const auth = firebase.auth();
const googleAuthProvider = new firebase.auth.GoogleAuthProvider();
export { firebase, googleAuthProvider, auth, database };
Then, I added a firestore.js file:
import { firebase } from "./firebase";
import "firebase/firestore";
import { notification } from "antd";
firebase.firestore().settings({ timestampsInSnapshots: true });
const handleError = error => {
if (error === "failed-precondition") {
notification.open({
message: "Error",
description:
"Multiple tabs open, offline data only works in one tab at a a time."
});
} else if (error === "unimplemented") {
notification.open({
message: "Error",
description: "Cannot save offline on this browser."
});
}
};
export default firebase
.firestore()
.enablePersistence()
.then(() => firebase.firestore())
.catch(err => {
handleError(err.code);
return firebase.firestore();
});
And then I call firestore in my actions file:
import firestore from "../firebase/firestore";
return firestore
.then(db => {
var newData = db
.collection("Users")
.doc(uid)
.collection("userData")
.doc();
newData.set(data);
var id = newData.id;
dispatch(addData({ id, ...data }));
})
.catch(err => {
// notification
});
Essentially, I separated out my redux and Firestore, but ultimately they are connected through the Firestore id.

Resources