已关闭。此问题需要超过focused。当前不接受答案。
**想要改进此问题吗?**更新此问题,使其仅关注editing this post的一个问题。
昨天关门了。
Improve this question
我正在做一个react原生多人游戏。我用firebase firestore作为我的后台,有一个游戏使用了大量的读取,当我为更多的用户发布这个应用程序时,我一定会检查一下免费计划。我想知道是否有人可以调整代码,减少每个游戏的读取。
export function MultiGame({ route, navigation }) {
const theme = useContext(themesContext);
const getId = route.params.gameId;
const getChosenDeck = route.params.getChosenDeckJoin;
const { user } = useAuth();
const [timeTill, setTimeTill] = useState(120);
useEffect(() => {
if (timeTill > 0) {
const intervalId = setTimeout(() => {
setTimeTill(timeTill - 1);
}, 1000); // decrement timer every second
return () => clearTimeout(intervalId);
}
}, [timeTill]);
// useEffect(() => {
// if (bothPlayersJoined) {
// setTimeout(() => {
// setBothPlayersJoined(true);
// }, 3000);
// }
// }, [firstLoadNum, bothPlayersJoined, bothPlayersInGame]);
useEffect(() => {
const docRef = doc(db, "games", getId);
const checkIfData = onSnapshot(docRef, (doc) => {
if (!doc.data()) {
navigation.navigate("Home");
}
});
const checkForPlayAgain = onSnapshot(docRef, (doc) => {
if (doc.data()) {
setUserOneClickPlayAgain(doc.data().userOneClickPlayAgain);
} else {
console.log("no data in doc.data()");
}
});
const checkForBothPlayers = onSnapshot(docRef, (doc) => {
if (doc.data()) {
if (doc.data().playerOne && doc.data().playerTwo) {
setPlayerTwo(doc.data().playerTwo);
}
} else {
console.log("no data in doc.data()");
}
});
// const delteAfterTime = onSnapshot(docRef, (doc) => {
// if (doc.data().playerOne && !doc.data().playerTwo && timeTill <= 0) {
// deleteDoc(docRef);
// }
// });
const unsubscribe = onSnapshot(docRef, (doc) => {
if (doc.data().playerOne && doc.data().playerTwo) {
setBothPlayersInGame(true);
setGameDeck(JSON.parse(doc.data().gameDeck));
setUserOneClickPlayAgain(doc.data().userOneClickPlayAgain);
setMultiUserOneScore(doc.data().playerOneScore);
setMultiUserTwoScore(doc.data().playerTwoScore);
setMultiUserOneIndex(doc.data().playerOneIndex);
setMultiUserTwoIndex(doc.data().playerTwoIndex);
setCurrentIndex(doc.data().currentIndex);
setPlayerOne(doc.data().playerOne);
// setPlayerTwo(doc.data().playTwo);
setRoundOverMulti(doc.data().roundOverMulti);
setMultiNotInDeckOne(doc.data().multiNotInDeckOne);
setMultiNotInDeckTwo(doc.data().multiNotInDeckTwo);
setUserOneDeck(JSON.parse(doc.data().multiDefaultUserOne));
setUserTwoDeck(JSON.parse(doc.data().multiDefaultUserTwo));
setMultiStartDisabled(doc.data().multiStartDisabled);
setNumberRounds(doc.data().numRounds);
} else if (doc.data().playerOne && !doc.data().playerTwo) {
setPlayerOne(doc.data().playerOne);
setNumberRounds(doc.data().numRounds);
if (
!doc.data().gameDeck &&
!doc.data().multiUserOneDeck &&
!doc.data().multiUserTwoDeck
) {
updateDoc(docRef, {
gameDeck: stringDeck,
multiDefaultUserOne: multiDefaultUserOne,
multiDefaultUserTwo: multiDefaultUserTwo,
});
}
if (doc.data().playerOne && !doc.data().playerTwo && timeTill <= 0) {
deleteDoc(docRef);
} else {
// console.log("already hase deck");
}
} else {
console.log("one player is in the game");
}
});
return () => {
unsubscribe();
checkIfData();
checkForPlayAgain();
checkForBothPlayers();
};
}, [getId, timeTill]);
useEffect(() => {
const docRef = doc(db, "games", getId);
const unsubscribe = onSnapshot(docRef, (doc) => {
setGameCountDown(doc.data()?.gameCountDown);
if (doc.data()?.playerOne !== null && doc.data()?.playerTwo) {
if (getId === doc.data()?.id) {
setTimeout(() => {
// setGameCountDown(0);
updateDoc(docRef, {
gameCountDown: 0,
});
}, 3000);
}
}
});
return () => {
unsubscribe();
};
}, [getId]);
const getUSerChosenDeck = () => {
if (getChosenDeck === "gameDecks") {
return gameDecks;
}
if (getChosenDeck === "monsterDeck") {
return monsterDeck;
}
if (getChosenDeck === "foodDeck") {
return foodDeck;
}
if (getChosenDeck === "flagDeck") {
return flagDeck;
}
if (getChosenDeck === "characterDeck") {
return characterDeck;
}
if (getChosenDeck === "nhlDeck") {
return nhlDeck;
}
if (getChosenDeck === "animalDeck") {
return animalDeck;
}
};
const shuffleArrayPreGame = (array) => {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
};
const shuffledArray = shuffleArrayPreGame(
getUSerChosenDeck().map((deck) => shuffleArrayPreGame(deck))
);
const userOneRandom = (array) => {
let randomIndex = Math.floor(Math.random() * array.length);
if (randomIndex === 0) {
randomIndex = 1;
}
return array[randomIndex];
};
let userOneChoice = userOneRandom(shuffledArray);
const userTwoRandom = (array) => {
let randomIndex = Math.floor(Math.random() * array.length);
if (randomIndex === 0 || randomIndex === userOneChoice) {
randomIndex = 1;
}
return array[randomIndex];
};
const multiDefaultUserOne =
shuffledArray && JSON.stringify(userOneRandom(shuffledArray));
const multiDefaultUserTwo =
shuffledArray && JSON.stringify(userTwoRandom(shuffledArray));
const stringDeck = shuffledArray && JSON.stringify(shuffledArray);
const [numberRounds, setNumberRounds] = useState(0);
const [currentIndex, setCurrentIndex] = useState(0);
const [userTwoDeck, setUserTwoDeck] = useState();
const [userOneDeck, setUserOneDeck] = useState();
const [userOneScore, setUserOneScore] = useState(0);
const [userTwoScore, setUserTwoScore] = useState(0);
const [multiUserOneScore, setMultiUserOneScore] = useState();
const [multiUserTwoScore, setMultiUserTwoScore] = useState();
const [multiUserOneIndex, setMultiUserOneIndex] = useState();
const [multiUserTwoIndex, setMultiUserTwoIndex] = useState();
const [multiStartDisabled, setMultiStartDisabled] = useState();
const [firstLoadNum, setFirstLoadNum] = useState(0);
const [gameCountDown, setGameCountDown] = useState(3);
const [timer, setTimer] = useState(120); // 2 minutes in seconds
useEffect(() => {
if (timer > 0) {
const intervalId = setTimeout(() => {
setTimer(timer - 1);
}, 1000); // decrement timer every second
return () => clearTimeout(intervalId);
}
}, [timer]);
const formatTime = (count) => {
const minutes = Math.floor(count / 60);
const seconds = count % 60;
const formatted = `${minutes.toString().padStart(2, "0")}:${seconds
.toString()
.padStart(2, "0")}`;
return formatted;
};
const getDocData = async () => {
const docRef = doc(db, "games", getId);
const docSnap = await getDoc(docRef);
if (docSnap.data().gameDeck) {
// console.log("Document data:", docSnap.data());
// const docSnap = await getDoc(docRef);
const parse = JSON.parse(docSnap.data().gameDeck);
setGameDeck(parse);
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}
};
useEffect(() => {
getDocData();
}, [getId]);
const [gameDeck, setGameDeck] = useState([]);
const [gameOver, setGameOver] = useState(false);
const [multiNotInDeckOne, setMultiNotInDeckOne] = useState();
const [multiNotInDeckTwo, setMultiNotInDeckTwo] = useState();
const [roundOverMulti, setRoundOverMulti] = useState(true);
const [showGameOverMessage, setShowGameOverMessage] = useState(false);
const [progress, setProgress] = useState(0);
const [bothPlayersInGame, setBothPlayersInGame] = useState(false);
const [playerOne, setPlayerOne] = useState();
const [playerTwo, setPlayerTwo] = useState();
const [userOneClickPlayAgain, setUserOneClickPlayAgain] = useState();
const [matchingID, setMatchingID] = useState();
const [matchingIDTwo, setMatchingIDTwo] = useState();
const [bothPlayersJoined, setBothPlayersJoined] = useState(true);
const shortendEmail = playerOne ? playerOne.split("@")[0] : "";
const shortendEmailTwo = playerTwo ? playerTwo.split("@")[0] : "Waiting...";
const findMatchingIdUserOne = () => {
gameDeck[currentIndex] &&
gameDeck[currentIndex].forEach((gameDeckItem) => {
let found = userOneDeck?.find((userDeckItem) => {
return gameDeckItem.id === userDeckItem.id;
});
if (found) {
setMatchingID(found.id);
return;
}
});
};
const findMatchingIdUserTwo = () => {
gameDeck[currentIndex] &&
gameDeck[currentIndex].forEach((gameDeckItem) => {
let found = userTwoDeck?.find((userDeckItem) => {
return gameDeckItem.id === userDeckItem.id;
});
if (found) {
setMatchingIDTwo(found.id);
return;
}
});
};
useEffect(() => {
findMatchingIdUserOne();
findMatchingIdUserTwo();
console.log(matchingID, "player one");
console.log(matchingIDTwo, "player two");
}, [currentIndex, gameDeck]);
useEffect(() => {
if (multiUserOneScore + multiUserTwoScore >= numberRounds) {
// updateDoc(doc(db, "games", getId), {
// playerTwo: null,
// });
const timeout = setTimeout(() => {
setGameOver(true);
}, 900);
return () => clearTimeout(timeout);
}
}, [multiUserOneScore, multiUserTwoScore, numberRounds]);
useEffect(() => {
if (multiStartDisabled) {
const timeout = setTimeout(() => {
updateDoc(doc(db, "games", getId), {
multiStartDisabled: false,
});
}, 850);
return () => clearTimeout(timeout);
}
}, [multiStartDisabled]);
useEffect(() => {
if (multiNotInDeckOne) {
const timeout = setTimeout(() => {
updateDoc(doc(db, "games", getId), {
multiNotInDeckOne: false,
});
}, 1500);
return () => clearTimeout(timeout);
}
}, [multiNotInDeckOne]);
useEffect(() => {
if (multiNotInDeckTwo) {
const timeout = setTimeout(() => {
updateDoc(doc(db, "games", getId), {
multiNotInDeckTwo: false,
});
}, 1500);
return () => clearTimeout(timeout);
}
}, [multiNotInDeckTwo]);
useEffect(() => {
if (numberRounds) {
const totalScore = multiUserOneScore + multiUserTwoScore;
const newProgress = totalScore / numberRounds;
setProgress(newProgress);
}
}, [multiUserOneScore, multiUserTwoScore]);
//write a useeffect that updates the progress bar when the score changes
useEffect(() => {
if (gameOver) {
setTimeout(() => {
setShowGameOverMessage(true);
setTimeTill(120);
updateDoc(doc(db, "games", getId), {
userOneClickPlayAgain: false,
});
}, 500);
}
}, [gameOver]);
const resetGame = () => {
updateDoc(doc(db, "games", getId), {
gameDeck: stringDeck,
playerOneScore: 0,
playerTwoScore: 0,
playerOneIndex: 28,
playerTwoIndex: 29,
multiDefaultUserOne: multiDefaultUserOne,
multiDefaultUserTwo: multiDefaultUserTwo,
userOneClickPlayAgain: true,
playerTwo: playerOne === user?.email ? null : user?.email,
gameCountDown: 3,
// roundOverMulti: true,
// multiStartDisabled: true,
// multiNotInDeckOne: false,
// multiNotInDeckTwo: false,
// multiRoundOver: true,
});
setBothPlayersJoined(true);
setBothPlayersInGame(false);
setUserOneScore(0);
setUserTwoScore(0);
setGameOver(false);
setShowGameOverMessage(false);
// setTimeout(
// () =>
// updateDoc(doc(db, "games", getId), {
// userOneClickPlayAgain: false,
// }),
// 35000
// );
};
const handleClick = (clickedEmoji, user) => {
if (gameDeck[currentIndex].some((emoji) => emoji.id === clickedEmoji)) {
if (user === "userOne") {
setUserOneScore(userOneScore + 1);
updateDoc(doc(db, "games", getId), {
playerOneScore: userOneScore + 1,
playerOneIndex: currentIndex,
multiDefaultUserOne: JSON.stringify([...gameDeck[currentIndex]]),
});
} else {
setUserTwoScore(userTwoScore + 1);
updateDoc(doc(db, "games", getId), {
playerTwoScore: userTwoScore + 1,
playerTwoIndex: currentIndex,
multiDefaultUserTwo: JSON.stringify([...gameDeck[currentIndex]]),
});
}
updateDoc(doc(db, "games", getId), {
roundOverMulti: false,
multiStartDisabled: true,
});
setTimeout(
() =>
updateDoc(doc(db, "games", getId), {
roundOverMulti: true,
}),
500
);
if (currentIndex === gameDeck.length - 1) {
const beforeShuffle = gameDeck;
shuffleArray(beforeShuffle);
setGameDeck(beforeShuffle);
setCurrentIndex(0);
} else {
updateDoc(doc(db, "games", getId), {
currentIndex: currentIndex + 1,
});
}
} else {
if (user === "userOne") {
updateDoc(doc(db, "games", getId), {
multiNotInDeckOne: true,
});
} else {
updateDoc(doc(db, "games", getId), {
multiNotInDeckTwo: true,
});
}
}
};
const shuffleArray = (array) => {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
};
const goToHome = () => {
setTimeout(() => {
navigation.navigate("Home");
}, 170);
setTimeout(() => {
deleteDoc(doc(db, "games", getId));
}, 370);
};
const resetGameDelay = () => {
setTimeout(() => {
resetGame();
}, 170);
};
const progressColor = "#263238";
//if bother player not in game return waiting screen
const shouldBeDisabledDeckOne = () => {
if (playerOne === user?.email) return false;
if (
gameOver === true ||
multiStartDisabled === true ||
multiNotInDeckOne === true
)
return true;
return false;
};
const shouldBeDisabled = () => {
if (gameOver === true || multiStartDisabled === true) return true;
if (playerOne === user?.email && multiNotInDeckOne) return true;
if (playerOne !== user?.email && multiNotInDeckTwo) return true;
if (gameCountDown === 3) return true;
return false;
};
我试着改变一些主要的使用效果,而不是一个快照,但没有工作得很好。
1条答案
按热度按时间thtygnil1#
我从你的代码中可以理解的是,你在用户打开应用程序时调用firebase,如果用户的id存在,你就从数据库中提取数据。
解决方案为了减少firebase请求的数量,我建议您使用
AsyncStorage
或CotextAPI
。您可以保存每次用户打开应用时获取的用户基本详细信息,这将使您的应用响应更快,并根据您的要求减少firebase请求的数量。