Every time I reload my web app the first time I try call getDBRecords() it doesn't work (the code inside the then statement doesn't execute), but then if I try again immediately it will work, and will continue to work from then on until I reload the app.
How can I get the DB call to work first time? Is it something to do with Promises /Async await?
Any help is much appreciated!
firebase.js Installation/Configuration
import * as firebase from 'firebase'
const firebaseConfig = {
apiKey: "",
authDomain: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: "",
measurementId: "",
databaseURL: ""
};
let app
if (firebase.apps.length === 0) {
app = firebase.initializeApp(firebaseConfig)
} else {
app = firebase.app();
}
const auth = firebase.auth()
const db = firebase.firestore();
export { db, auth };
DataContext
import React, { useContext, useState, useEffect } from 'react'
import { db } from '../../firebase'
const DataContext = React.createContext()
export function useData() {
return useContext(DataContext)
}
export function DataProvider({ children }) {
const [result, setResult] = useState('')
function getDBRecords() {
setResult('')
var results = []
var promise = db.collection("COLLECTION_NAME").where("attr", ">", 10).get()
promise.then((querySnapshot) => {
querySnapshot.forEach((doc)=>{
results.push(doc.data())
})
setResult(results)
}).catch((error) => {
console.log("Error getting document:", error);
});
return result
}
const value = {
testDBRead,
testDBWrite,
getLastFew,
propSearch
}
return (
<DataContext.Provider value={value}>
{children}
</DataContext.Provider>
)
You should call your function in useEffect
useEffect(() => {
getDBRecords();
},[])
Figured it out, posting the answer for anyone else who runs into the problem.
I needed to give the then() function after the promise a function it could callback, I think, not sure how it works but by passing the useState set state function into my useContext() and calling that function inside my then function the data is updated.
In the screen.js file:
// Importing the function from a useContext
const { fetchSingleDoc } = useData()
const [doc, setDoc] = useState('')
// Here I call the fetchSingleProp and pass both the ID of the document I wish to get and the setter function.
const handleFetchDoc = (doc_id) => {
console.log("Fetching Property: ", x)
fetchSingleProp(doc_id, setDoc)
}
In the DataContext.js file:
// The solution for me was to add the setDoc function and call it inside the then call.
function fetchSingleDoc(prop_id, setDoc) {
var propRef = db.collection("PROD-JOIN").doc(props[prop_id]);
propRef.get().then((doc) => {
if (doc.exists) {
const data = doc.data()
setDoc(data)
} else {
console.log("No such document!");
}
}).catch((error) => {
console.log("Error getting document:", error);
});
}
Not really sure whats happening but I think the then part of the statement hasnt returned and so needs a function it can "call back" to pass the value back to the right place.
Related
I have config/firebase.ts:
import { initializeApp, cert } from 'firebase-admin/app';
import { getFirestore } from 'firebase-admin/firestore'
const firebaseAdminApp = initializeApp({
credential: cert({
privateKey: process.env.NEXT_PUBLIC_FIREBASE_PRIVATE_KEY.replace(/\\n/g, '\n'),
clientEmail: process.env.NEXT_PUBLIC_FIREBASE_SERVICE_EMAIL,
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID
}),
databaseURL: `https://${process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID}.firebaseio.com`
});
const firestore = getFirestore(firebaseAdminApp);
export default firestore
and when trying to upsert, I have:
import firestore from "../config/firebaseAdmin";
const upsertInstance = async (instance: Instance) => {
const hashedUri = createHash('sha256').update(instance.uri).digest('hex')
const res = await firestore.doc(`instances/${hashedUri}`).set(instance);
return res
}
but I get:
Error: expected a function
What am I doing wrong?
Firebase Admin is not totally modular yet like the client SDK yet so you would have to use namespaced syntax. Admin SDK's Firestore instance won't work perfectly with client SDK functions. Try refactoring the code as shown below:
export const db = getFirestore(firebaseAdminApp);
import { db } from "../path/to/firebase"
const upsertInstance = async (instance: Instance) => {
const res = await db.doc(`instances/${instance.uri}`).set(instance);
return res;
}
Checkout the documentation for more information.
When updating a document in v9 of firebase/firestore I got an error and I've been following the official documentation and not sure what I'm doing wrong:
import { initializeApp } from "firebase/app";
import { getFirestore, updateDoc, doc} from 'firebase/firestore';
import firebaseConfig from '../utils/firestore';
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
function updateSeries(docID, name, desc) {
const data = {
name: name,
desc: desc,
lastUpdatedAt: Timestamp.now(),
}
const seriesDocRef = doc(db, "MY_COL", docID)
return new Promise((resolve, reject) => {
updateDoc(seriesDocRef, data).then(() => {
resolve();
}).catch((e) => {
reject(e);
})
})
}
When I call this function I get this error:
errors.ts:94 Uncaught FirebaseError: Invalid document reference. Document references must have an even number of segments, but MY_COL has 1.
If the values in passed into the doc function are undefined or falsy it can cause this error. Please check if the db and docID variables are defined in:
const seriesDocRef = doc(db, "MY_COL", docID)
I'm trying to retrieve from a realtime db I started by init the app with the configuration like so
import {initializeApp} from 'firebase/app';
import {getDatabase} from 'firebase/database';
let config = {
apiKey: 'xxxxxxxxxxxx',
authDomain: 'xxxxxxxxxxxx',
...
};
const app = initializeApp(config);
const database = getDatabase(app);
then when I try using the database variable it crashes
componentDidMount() {
database
.ref(`master/tickets`)
.once('value', snapshot => {
var obj = snapshot.val();
console.log('obj :', obj);
})
.catch(error => {
console.log(error);
});
}
I also have tried firebase.database.ref() it shows error cannot find variable firebase
What I am doing wrong? It was working fine in previous builds
The Firebase Web SDK underwent major breaking changes with the update to V9.0.0.
Please see the upgrade guide for details on how to modify older patterns to the new API.
import { ref, get } from "firebase/database";
import { database } from "...";
/* ... */
componentDidMount() {
get(ref(database, 'master/tickets'))
.then(snapshot => {
const obj = snapshot.val();
console.log('obj :', obj);
})
.catch(error => {
console.log(error);
});
}
I can't get data from firebase. Firebase.js is using for initialization of firebase and in App.js I am trying to get and work with it.
Now when I'm trying to get data and display it in browser, I see just blank page. Looks like I didn't get any data.
In some reasons I even can't console.log from stocksRef.on('value', (dataSnapshot) and I can't check what data I got and did I get it.
Please, help me to fix it.
App.js
class StocksList extends Component {
constructor(props){
super(props);
this.state = {
stocks: []
}
}
componentDidMount() {
const stocksRef = firebase.database().ref('list');
console.log('popopok', stocksRef)
stocksRef.on('value', (dataSnapshot) => {
let list = dataSnapshot.val();
this.setState({
stocks: Object.values(list)
})
})
}
render() {
return (
<div>
{this.state.stocks.map((item) => {
return (
<div>
<p>ISIN: {item.isin}</p>
<p>issuer: {item.issuer}</p>
<p>issuerCode: {item.issuerCode}</p>
<p>ISIN: {item.isin}</p>
<p>nominal: {item.nominal} {item.currency}</p>
<p>form: {item.form}</p>
<p>vyd: {item.vyd}</p>
</div>
)
})}
</div>
)
}
}
export default StocksList;
firebase.js
import firebase from 'firebase'
let config = {
apiKey: ******,
authDomain: ******,
databaseURL: ******,
projectId: ******,
storageBucket: ******,
messagingSenderId: ******,
appId: ******
};
firebase.initializeApp(config);
export default firebase;
You need to make access permission rules at firebase console.
As far as I know you need to make some rules for Access data in firebase real-time-database.
And If you want to know about firebase permission rule, just read my reference
You can check it with next code's error
try{
stocksRef.on('value', (dataSnapshot) => {
let list = dataSnapshot.val();
this.setState({
stocks: Object.values(list)
})
})
} catch(error) {
console.log(error);
}
Reference
Database rules - Firebase Documents
Try like this
async componentDidMount() {
const stocksRef = await firebase.database().ref('list');
console.log('popopok', stocksRef)
stocksRef.on('value', (dataSnapshot) => {
let list = dataSnapshot.val();
this.setState({
stocks: Object.values(list)
})
})
}
I am importing 'firebaseApp' from a file where I have done all the setup of firebase and I have implemented email, google and Facebook authentication but when I am implementing the phone number auth the ReCaptcha is not a constructor I am using ReactJs functional component.
Is there any way of implementing phone number auth without ReCaptcha or if not how can I fix the error.
Setup of firebase
import firebase from 'firebase/app';
import 'firebase/auth'
import 'firebase/firestore';
// Web app's Firebase configuration
var firebaseConfig = {
apiKey: "",
authDomain: "",
databaseURL: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: ""
};
// Initialize Firebase
export const firebaseApp = firebase.initializeApp(firebaseConfig);
export const auth = firebase.auth();
export const db = firebase.firestore();
export const google_provider = new firebase.auth.GoogleAuthProvider();
export const facebook_provider = new firebase.auth.FacebookAuthProvider();
This is the place I am taking the number as user input and sending the OTP for verification but the sample code number is hardcoded.
import { firebaseApp, auth } from '../../../firebase/firebasesetup'
function Form() {
const setuprecaptcha = () => {
window.recaptchaVerifier = new firebaseApp.auth.RecaptchaVerifier('recaptcha-container',
{
'size': 'invisible',
'callback': function (response) {
console.log("captcha resolved");
// sendsms();
}
});
}
const sendsms = () => {
setuprecaptcha();
var phoneNumber = '+918220310506';
var appVerifier = window.recaptchaVerifier;
auth.signInWithPhoneNumber(phoneNumber, appVerifier)
.then(function (confirmationResult) {
window.confirmationResult = confirmationResult;
}).catch(function (error) {
alert("not sent")
});
}
return (
<input type="text" placeholder="Mobile" value={mob}
onChange={e => setMob(e.target.value)} />
<div id="recaptcha-container"></div>
<button onClick={sendsms} id='sign-in-button'>Send otp</button>
)
}
export default Form
Ok, so I am answering My own question. This kind of looks Weird but still if anyone of you faces the same problem as mine.
2 things I need to solve in the firebase_setup file and add the main function in React functional component. (Total 3 updates)
firebase_setup file
first
import firebase from 'firebase'; and not import firebase from 'firebase/app';
second
firebase.initializeApp(firebaseConfig); export const firebaseApp = firebase
React functional component
import { firebaseApp} from './firebase_setup';
const sendsms = () => {
//If you want to make the recaptcha invisible
var recaptcha = new firebaseApp.auth.RecaptchaVerifier('recaptcha-container', {
'size': 'invisible'
});
//If you want to make the recaptcha visible
var recaptcha = new firebaseApp.auth.RecaptchaVerifier('recaptcha-container');
//Your phone number with the country code
var number = '+**********';
//actual code begins here
auth.signInWithPhoneNumber(number, recaptcha).then(function (e) {
var code = prompt("enter the code sent to your mobile number");
if (code === null) return;
e.confirm(code).then(function (result) {
alert(result.user + ' verified ')
}).catch(function (error) {
alert('Could not verify,Please try again');
});
}).catch(function (error) {
alert('Please try again.We were unable to reach your phone.Select the correct code and the phone number');
});
}