trying to import data from firebase, however i get thrown this error back:REACT: TypeError: Cannot read properties of undefined (reading 'map').
Making a project that monitors health of cloud functions and if they are working. Any help would be much appreciated. :)
app.js- the map function is in app.js {
45 | </Divider>
46 |
47 | {user ? (
> 48 | <Card.Group itemsPerRow="4">
| ^ 49 | {cloudFucntions.map((cloudFunction) => {
50 | return (
51 | <Cards
}
import "./App.css";
import "semantic-ui-css/semantic.min.css";
import { Container, Divider, Card } from "semantic-ui-react";
import Header from "./components/Header";
import Cards from "./components/Cards/index";
import { useState, useEffect } from "react";
import { AppProvider } from "./Context/Context.js";
import "firebase/compat/auth";
import {} from "firebase/firestore";
import * as FirestoreService from "./components/service/firebase";
import firebase from "@firebase/app-compat";
function App() {
const [user, setUser] = useState(null);
const [cloudFucntions, setCloudFucntions] = useState();
const [setError] = useState();
useEffect(() => {
firebase.auth().onAuthStateChanged((user) => {
setUser(user);
const unsubscribe = FirestoreService.getCloudFunctionItems(
(querySnapshot) => {
const updatedCloundFunctions = querySnapshot.docs.map((docSnapshot) =>
docSnapshot.data()
);
setCloudFucntions(updatedCloundFunctions);
console.log(updatedCloundFunctions);
},
(error) => setError("list-item-get-fail")
);
return unsubscribe;
});
}, []);
return (
<AppProvider>
<div>
<Container>
<Header />
<Divider horizontal section>
Cloud Function Monitor
</Divider>
{user ? (
<Card.Group itemsPerRow="4">
{cloudFucntions.map((cloudFunction) => {
return (
<Cards
key={cloudFunction.id}
cloudFunctions={cloudFunction}
></Cards>
);
})}
</Card.Group>
) : (
<h2> Please sign in using the button in the top right. </h2>
)}
</Container>
</div>
</AppProvider>
);
}
export default App;
firebase.js:
import firebase from "firebase/compat/app";
import "firebase/compat/auth";
import { initializeApp } from "firebase/app";
import {
getFirestore,
query,
orderBy,
onSnapshot,
collection,
getDoc,
getDocs,
addDoc,
updateDoc,
doc,
serverTimestamp,
arrayUnion,
} from "firebase/firestore";
const firebaseConfig = {
apiKey: "xxx",
authDomain: "xxx.firebaseapp.com",
projectId: "dxxxxdata-d1",
storageBucket: "xxx-reportingdata-d1.appspot.com",
messagingSenderId: "xxxxxxxx",
appId: "xxxxxxxx",
measurementId: "G-xxxxxxx",
};
firebase.initializeApp(firebaseConfig);
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
export const getCloudFunctionItems = (snapshot, error) => {
const itemsColRef = collection(db, "cloudFunctionsMonitor");
const itemsQuery = query(itemsColRef);
return onSnapshot(itemsQuery, snapshot, error);
};
export const getCloudFunction = (cloudFunctionId) => {
const cloudDocRef = doc(db, "cloudFunction", cloudFunctionId);
return getDoc(cloudDocRef);
};
export const auth = firebase.auth();
const provider = new firebase.auth.GoogleAuthProvider();
provider.setCustomParameters({ prompt: "select_account" });
export const signInWithGoogle = () => auth.signInWithPopup(provider);
export default firebase;
cards/index.js
import "../../App";
import "semantic-ui-css/semantic.min.css";
import { Icon, Card, Button } from "semantic-ui-react";
import "semantic-ui-css/semantic.min.css";
import React, { Component } from "react";
import "semantic-ui-css/semantic.min.css";
export default class Cards extends Component {
render() {
return (
<Card color={this.props.cloudFunction.functionColor}>
{/* <h1> lastrunload: {this.propps.app.updatedCloundFunctions}</h1> */}
<Card.Content>
<Card.Header>
{this.props.cloudFunction.cardFunctionHeader}
</Card.Header>
<Card.Description>
{this.props.cloudFunction.cardFunctionDescription}
</Card.Description>
</Card.Content>
<Card.Content extra>
<Icon name="cog" />
{this.props.cloudFunction.functionRunTime}
<br />
<Icon name="clock" />
{this.props.cloudFunction.functionLastRun}
<br />
<Icon name="angle double down" />
{this.props.cloudFunction.functionLastInsert}
</Card.Content>
<Card.Content extra>
<div className="ui two buttons">
<Button basic color={this.props.cloudFunction.functionColor}>
{this.props.cloudFunction.functionButton}
</Button>
</div>
</Card.Content>
</Card>
);
}
}
CodePudding user response:
add checking for the undefined
, before going for .map()
on undefined,
checking and then call only when not null or undefined,
<Card.Group itemsPerRow="4">
{cloudFucntions && cloudFucntions.map((cloudFunction) => {
return (
<Cards
key={cloudFunction.id}
cloudFunctions={cloudFunction}
></Cards>
);
})}
</Card.Group>
const unsubscribe = FirestoreService.getCloudFunctionItems(
(querySnapshot) => {
const updatedCloundFunctions = querySnapshot && querySnapshot.docs && querySnapshot.docs.map((docSnapshot) =>
docSnapshot.data()
);
setCloudFucntions(updatedCloundFunctions);
console.log(updatedCloundFunctions);
},
(error) => setError("list-item-get-fail")
);
return unsubscribe;
});