【发布时间】:2022-01-17 13:46:27
【问题描述】:
编辑:我知道它与模拟器有关,因为没有它们它可以正常工作。
我正在关注course for Next js,我正在使用 Firebase 模拟器(它建议这样做,但没有教程可以这样做,因为它非常简单),我正在尝试从 firestore 读取一些数据用户,但它总是得到错误,Failed to get document because the client is offline。 auth 模拟器工作正常,但 firestore 没有。即使我与互联网断开连接(我不是因为我正在写这个问题并且可以访问任何网站)我知道为什么它会出现该错误,因为该网站托管在下一个 js 上。这是我在课程中制作的用于连接到 Firebase 的自定义钩子:
import { initializeApp } from "firebase/app";
import {
getAuth,
signInWithPopup,
signOut,
signInAnonymously,
GoogleAuthProvider,
connectAuthEmulator,
} from "firebase/auth";
import { getFirestore, doc, onSnapshot, connectFirestoreEmulator, getDoc } from "firebase/firestore";
const firebaseConfig = {
apiKey: "MY APIKEY",
authDomain: "My AUTH DOMAIN",
projectId: "nextfirE (in the course i am using we are making are making a blog type app called nextfire)",
storageBucket: "STOREAGEBUKET DOMAIN",
messagingSenderId: "messagingSenderId",
appId: "aPP id",
measurementId: "measurementId",
};
const firebase = initializeApp(firebaseConfig);
const auth = getAuth();
const db = getFirestore()
export {
GoogleAuthProvider,
auth,
signInWithPopup,
signOut,
signInAnonymously,
db,
doc,
onSnapshot,
getDoc
};
if (window.location.hostname === "localhost") {
connectAuthEmulator(auth, "http://localhost:9099");
connectFirestoreEmulator(db, "https://localhost", 8080)
}
这是一个用户名表单,这里是处理表单的反应组件:
function Username() {
const [formValue, setFormValue] = useState("");
const [isValid, setIsValid] = useState(false);
const [loading, setLoading] = useState(false);
const { user, username } = useContext(UserContext);
useEffect(() => {
checkUsername(formValue);
}, [formValue]);
const onChange = (e) => {
const val = e.target.value.toLowerCase();
const regex = /^(?=[a-zA-Z0-9._]{3,15}$)(?!.*[_.]{2})[^_.].*[^_.]$/;
if (val.length < 3) {
setFormValue(val);
setLoading(false);
setIsValid(false);
}
if (regex.test(val)) {
setFormValue(val);
setLoading(true);
setIsValid(false);
}
};
const checkUsername = useCallback(
debounce(async (username: string) => {
if (username.length >= 3) {
const ref = doc(db, `usernames/${username}`);
const docSnap = await getDoc(ref);
if (docSnap.exists()) {
setIsValid(true);
setLoading(false);
} else {
setIsValid(false);
setLoading(false);
}
}
}, 500),
[]
);
return (
!username && (
<section>
<h3>Choose Your Username</h3>
<form>
<input
name="username"
placeholder="username"
value={formValue}
onChange={onChange}
/>
<button
type="submit"
className="btn-green"
disabled={!isValid}
>
Take Username
</button>
<h3>Debug State</h3>
<div>
Username: {formValue}
<br />
Loading: {loading.toString()}
<br />
Username Valid: {isValid.toString()}
</div>
</form>
</section>
)
);
}
它有一些正则表达式检查和长度检查,但是如果它通过了这些检查,则会进入 firestore,当我输入一个已经被使用的用户名时(如果它已经被使用,将会有一个以用户名作为名称存在的 firestore 文档的文档)显示错误需要几秒钟,但是当我输入一个尚未被使用的有效用户名时,它会立即给我一个错误。你能帮帮我吗?
谢谢
【问题讨论】:
-
另外,将您的代码修复为“connectFirestoreEmulator(db, "localhost", 8080)"
-
@Alien10 我已经发布了一个答案,以供将来遇到此问题的任何人参考。我已经涵盖了可能导致此错误的所有可能原因/原因。我什至指出您的解决方案是解决方案之一。请仔细阅读答案,如果您认为我的答案有用,请点击它左侧的点赞按钮 (▲)。
标签: reactjs firebase google-cloud-firestore next.js