編輯:我知道這與模擬器有關,因為沒有它們也能正常作業。
我正在學習 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 檔案存在) ) 顯示錯誤需要幾秒鐘,但是當我輸入一個未被使用的有效用戶名時,它會立即給我一個錯誤。你能幫我么?
謝謝
uj5u.com熱心網友回復:
感謝 Gourav BI 能夠找到答案。我只需要在 connectFirestoreEmulator 中洗掉 localhost 前面的 https:// 。我猜在 connectFirestoreEmulator 中,它們連接到 https:// 主機 埠(主機和埠是第二個和第三個引數)。感謝古拉夫 B!
uj5u.com熱心網友回復:
由于客戶端離線,無法獲取檔案
當您嘗試檢索單個檔案、您處于脫機狀態并且本地快取中不存在請求的檔案時,就會發生錯誤。在這種情況下,客戶端沒有關于檔案的資訊,也不知道它是否存在于后端。在重新建立網路連接之前,無法知道檔案是否存在。所以為了避免錯誤地報告檔案不存在,產生了這個錯誤。
通過在在線狀態下獲取檔案使其存在于本地快取中,可以在很大程度上避免這種情況。但是請注意,本地快取是一個快取,可能會從快取中逐出“陳舊”條目,以便為其他資料騰出空間。如果檔案中的資料不經常更改,您還可以通過注冊快照偵聽器addSnapshotListener()并使偵聽器保持活動狀態以確保檔案保留在本地快取中。此外,此錯誤可能有多種其他原因,其中一些是:
- 您試圖參考尚未創建的集合/檔案。因此,只需創建一個帶有虛擬檔案的集合,或者等待創建檔案并查看它是否作業正常。
- 實作 try ... 捕獲所有 get().await() 呼叫。未處理的例外可能導致此錯誤
- 通過更改模擬器的埠號解決了問題。如果 8080 不作業,請嘗試 8081,
同樣根據Firebase 檔案和GitHub 鏈接更改,
if (window.location.hostname === "localhost") {
connectAuthEmulator(auth, "http://localhost:9099");
connectFirestoreEmulator(db, "https://localhost", 8080) }
到
if (window.location.hostname === "localhost") {
connectAuthEmulator(auth, "http://localhost:9099");
connectFirestoreEmulator(db, "localhost", 8080) }
更新所有包并為您的 Web 應用程式啟用離線持久性,如下所示:
firebase.firestore().enablePersistence()
https://firebase.google.com/docs/firestore/manage-data/enable-offline
[5] 這也可能是因為OnCompleteListener在任務完成時觸發,要么失敗要么成功。為避免該錯誤,您可以單獨使用,OnSuccessListener并OnFailureListener
在任務成功時呼叫 OnSuccessListener,但如果發生上述錯誤,則會觸發 OnFailureListener,您可以onFailure()在偵聽器的方法中處理該錯誤。
[6] 將專案 ID 傳遞給 initializeApp 或設定環境變數時,請檢查專案 ID 是否正確。
admin.initializeApp({ projectId: "your-project-id" });
或者
export GCLOUD_PROJECT="your-project-id"
如果仍然遇到問題,請嘗試按照此檔案將您的應用程式連接到 Firestore Emulator,我還建議啟用除錯日志記錄以查看它是否提示客戶端無法連接的原因。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/381772.html
標籤:反应 火力基地 谷歌云firestore 下一个.js
上一篇:FirestorewithConverter在TS中回傳QueryDocumentSnapshot而不是Class
下一篇:join()方法末尾的乘數?
