在我的应用程序中,我试图添加一个使用getState()的新产品。userId作为键,这样如果我使用相同的电子邮件,我将在我的管理部分看到添加的产品,但有时,我无法添加产品,我的应用程序给我一个错误说:VirtualizedList: missing keys for items, make sure to specify a key or id property on each item or provide a custom keyExtractor
.
因此,出于调试目的,我检查了getState。userId我从redux得到不同的userId,这就是为什么我不能在我的管理区域看到我的产品,因为我已经添加了他们的ownerId===userId
。
但是,在重新加载或刷新应用程序后,我能够在那里看到我的产品,并且还能够在firebase上添加具有正确userId的产品。
存储/行动/Auth.js:
import { AsyncStorage } from "react-native";
let timer;
export const AUTHENTICATE = "AUTHENTICATE";
export const LOGOUT = "LOGOUT";
export const Authenticate = (userId, token, expiryTime) => {
return (dispatch) => {
dispatch(setLogoutTimer(expiryTime));
dispatch({ type: AUTHENTICATE, userId: userId, token: token });
};
};
export const signup = (email, password) => {
return async (dispatch) => {
const response = await fetch(
"https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=AIzaSyAnaJyjjGppk9-FiWocva_cP0vaMrKp4_4",
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
email: email,
password: password,
returnSecureToken: true,
}),
}
);
if (!response.ok) {
const responseData = await response.json();
const errorMessage = responseData.error.message;
if (errorMessage === "EMAIL_EXISTS") {
throw new Error("Email already exists");
}
}
const resData = await response.json();
console.log(resData);
dispatch(
Authenticate(
resData.idToken,
resData.localId,
parseInt(resData.expiresIn) * 1000
)
);
const expirationDate = new Date(
new Date().getTime() + parseInt(resData.expiresIn) * 1000
);
saveDataToStorage(resData.idToken, resData.localId, expirationDate);
};
};
export const login = (email, password) => {
return async (dispatch) => {
const response = await fetch(
"https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=AIzaSyAnaJyjjGppk9-FiWocva_cP0vaMrKp4_4",
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
email: email,
password: password,
returnSecureToken: true,
}),
}
);
if (!response.ok) {
const responseData = await response.json();
const errorMessage = responseData.error.message;
if (
errorMessage === "EMAIL_NOT_FOUND" ||
errorMessage === "INVALID_PASSWORD"
) {
throw new Error("Email or Password is wrong!!");
}
}
const resData = await response.json();
console.log(resData);
dispatch(
Authenticate(
resData.idToken,
resData.localId,
parseInt(resData.expiresIn) * 1000
)
);
const expirtationDate = new Date(
new Date().getTime() + parseInt(resData.expiresIn) * 1000
);
saveDataToStorage(resData.idToken, resData.localId, expirtationDate);
};
};
export const logout = () => {
clearLogoutTimer();
AsyncStorage.removeItem("userData");
return { type: LOGOUT };
};
const clearLogoutTimer = () => {
if (timer) {
clearTimeout(timer);
}
};
const setLogoutTimer = (expirationTime) => {
return (dispatch) => {
timer = setTimeout(() => {
dispatch(logout());
}, expirationTime);
};
};
const saveDataToStorage = (token, userId, expirtationDate) => {
AsyncStorage.setItem(
"userData",
JSON.stringify({
token: token,
userId: userId,
expiryDate: expirtationDate.toISOString(),
})
);
};
存储/行动/product.js:
import { createAsyncThunk } from "@reduxjs/toolkit";
import Product from "../../models/Product";
export const CREATE_PRODUCT = "CREATE_PRODUCT";
export const SET_PRODUCT = "SET_PRODUCT";
export const fetchProducts = () => {
return async (dispatch, getState) => {
const userId = getState().Auth.userId;
try {
const response = await fetch(
"https://shopping-app-62e38-default-rtdb.firebaseio.com/products.json"
);
if (!response.ok) {
throw new Error("Something went wrong!");
}
const resData = await response.json();
const loadedProducts = [];
for (const key in resData) {
loadedProducts.push(
new Product(
key,
resData[key].ownerId,
resData[key].title,
resData[key].imageUrl,
resData[key].description,
resData[key].price
)
);
}
dispatch({
type: SET_PRODUCT,
products: loadedProducts,
userProducts: loadedProducts.filter((prod) => prod.ownerId === userId),
});
} catch (error) {
throw error;
}
};
};
export const createProduct = (title, description, imageUrl, price) => {
return async (dispatch, getState) => {
const token = getState().Auth.token;
const userId = getState().Auth.userId;
console.log(getState());
const response = await fetch(
`https://shopping-app-62e38-default-rtdb.firebaseio.com/products.json?auth=${token}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title,
description,
imageUrl,
price,
ownerId: userId,
}),
}
);
const resData = await response.json();
console.log(userId);
dispatch({
type: CREATE_PRODUCT,
productData: {
id: resData.name,
title,
description,
imageUrl,
price,
ownerId: userId,
},
});
};
};
我尝试添加一个产品。但是我得到了同样的错误上面提到的。
console.log()- getState():
"Auth": Object {
"token": "9WwCUWtUeDaeHPHfURuBMSAaT553",
"userId": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjFiYjk2MDVjMzZlOThlMzAxMTdhNjk1MTc1NjkzODY4MzAyMDJiMmQiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL3NlY3VyZXRva2VuLmdvb2dsZS5jb20vc2hvcHBpbmctYXBwLTYyZTM4IiwiYXVkIjoic2hvcHBpbmctYXBwLTYyZTM4IiwiYXV0aF90aW1lIjoxNjI3MDY5NTM1LCJ1c2VyX2lkIjoiOVd3Q1VXdFVlRGFlSFBIZlVSdUJNU0FhVDU1MyIsInN1YiI6IjlXd0NVV3RVZURhZUhQSGZVUnVCTVNBYVQ1NTMiLCJpYXQiOjE2MjcwNjk1MzUsImV4cCI6MTYyNzA3MzEzNSwiZW1haWwiOiJ0ZXN0QGdtYWlsLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwiZmlyZWJhc2UiOnsiaWRlbnRpdGllcyI6eyJlbWFpbCI6WyJ0ZXN0QGdtYWlsLmNvbSJdfSwic2lnbl9pbl9wcm92aWRlciI6InBhc3N3b3JkIn19.Yq2CjY7anrwuQSt2N5nMSa3vUKh1gFiIuyO1Mw4-WQwbf_y9b9IYOHSG1YkXgFoyONOV71DOlT9JmWzGu9g2aFSKKUU3LffTY5WNQd5-Qm9QdbhHB0CtOAPJZ124FKiLLS0wJh0nVZKez8_6dH2ICOCw3e-lyktHOc6R11s_9xhEF1LLYv20b7BziWy6T_VHZOcUsiJbBwn09lx1SKkK4Ic3iEsWNeg-lSAgPJGO-sClUmwW9ffA3L1p8OvZubSNirKcGbRYkC323wXnlWv-tqqj6CW-uNc448i6qsmrs2RRR_f4WdLFN9dvv_PBjsf7V8r0m_HY4jjDzScNLLA4Hg",
},
"cart": Object {
"items": Object {},
"totalAmount": 0,
},
"orders": Object {
"orders": Array [],
},
"products": Object {
"availableProducts": Array [
Product {
"description": "Apple Macbook Air M1 chip",
"id": "-Md76UnJ1I1lNhGgldH3",
"imageUrl": "https://www.zdnet.com/a/hub/i/r/2020/11/23/77824151-c578-4431-8f00-633b1b7c0b99/thumbnail/770x433/3b5a2366cdeef2dc08730041abdcf426/macbook-air-m1-header.jpg",
"ownerId": undefined,
"price": 1200,
"title": "Macbook Air M1 2020",
},
Product {
"description": "Apple · iPhone 64GB Blue· iPhone 12 mini · iOS · 5.4 inches screen · Facial Recognition · 12 MP Front Camera · 12 MP Rear Camera · Smartphone · Wireless Charging",
"id": "-Mekel4gfFtgNUviidau",
"imageUrl": "https://encrypted-tbn3.gstatic.com/shopping?q=tbn:ANd9GcS_WPpNagW5q_-KAep1QkiInHfUYADs8qv84Z_FqKwMmW-J7nleMbl5y6muot5dxxRCOBZ-S_dYxxp_QpmTqzSnTj9oKQuH84kSCYjAZXT6UIsrnWJowbMMLw&usqp=CAE",
"ownerId": "9WwCUWtUeDaeHPHfURuBMSAaT553",
"price": 956.99,
"title": "Apple iPhone 12 Mini",
},
],
"userProducts": Array [],
},
}
console.log()标识:
eyJhbGciOiJSUzI1NiIsImtpZCI6IjFiYjk2MDVjMzZlOThlMzAxMTdhNjk1MTc1NjkzODY4MzAyMDJiMmQiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL3NlY3VyZXRva2VuLmdvb2dsZS5jb20vc2hvcHBpbmctYXBwLTYyZTM4IiwiYXVkIjoic2hvcHBpbmctYXBwLTYyZTM4IiwiYXV0aF90aW1lIjoxNjI3MDY5NTM1LCJ1c2VyX2lkIjoiOVd3Q1VXdFVlRGFlSFBIZlVSdUJNU0FhVDU1MyIsInN1YiI6IjlXd0NVV3RVZURhZUhQSGZVUnVCTVNBYVQ1NTMiLCJpYXQiOjE2MjcwNjk1MzUsImV4cCI6MTYyNzA3MzEzNSwiZW1haWwiOiJ0ZXN0QGdtYWlsLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwiZmlyZWJhc2UiOnsiaWRlbnRpdGllcyI6eyJlbWFpbCI6WyJ0ZXN0QGdtYWlsLmNvbSJdfSwic2lnbl9pbl9wcm92aWRlciI6InBhc3N3b3JkIn19.Yq2CjY7anrwuQSt2N5nMSa3vUKh1gFiIuyO1Mw4-WQwbf_y9b9IYOHSG1YkXgFoyONOV71DOlT9JmWzGu9g2aFSKKUU3LffTY5WNQd5-Qm9QdbhHB0CtOAPJZ124FKiLLS0wJh0nVZKez8_6dH2ICOCw3e-lyktHOc6R11s_9xhEF1LLYv20b7BziWy6T_VHZOcUsiJbBwn09lx1SKkK4Ic3iEsWNeg-lSAgPJGO-sClUmwW9ffA3L1p8OvZubSNirKcGbRYkC323wXnlWv-tqqj6CW-uNc448i6qsmrs2RRR_f4WdLFN9dvv_PBjsf7V8r0m_HY4jjDzScNLLA4Hg
经过一些刷新或再次登录,我能够看到我之前添加的产品,并且已经在firebase上,现在从管理区域中获取并显示,因为我从getState()中获得正确的userId。
注意:我上面尝试的产品没有添加,但是我已经添加的一些产品没有作为userId获取,我得到的是不正确的。
当我从firebase获得正确的userId时,这也是我的ownerId,然后我可以在我的管理区域看到我的产品。
我在userId而不是localId中获得idToken。我不知道为什么和如何解决这个问题。
问题似乎是你的Authenticate
部分:
// When defining Authenticate
export const Authenticate = (userId, token, expiryTime) => {
return (dispatch) => {
dispatch(setLogoutTimer(expiryTime));
dispatch({ type: AUTHENTICATE, userId: userId, token: token });
};
};
// In your signup and login
dispatch(
Authenticate(
resData.idToken,
resData.localId,
parseInt(resData.expiresIn) * 1000
)
);
您以错误的顺序传递参数,这将解释为什么您的userId/localId是您的令牌,反之亦然。