Firestore子集合在Redux上未加载

huangapple go评论81阅读模式
英文:

Firestore Subcollection Not Loading On Redux

问题

我在使用Redux Toolkit时遇到了一个问题,它没有更新Firestore DB子集的状态。Firebase身份验证字段正常工作,因为Redux会更新userId、firstName(displayName)和email字段,但来自Firestore的title和email字段未被更新。有什么想法吗?非常感谢!

请参见下面的代码示例:

// App.js
const dispatch = useDispatch();
useEffect(() => {
  getAuth().onAuthStateChanged(async (user) => {
    try {
      const docRef = doc(db, "users", user.uid)
      const docSnap = await getDoc(docRef)
      if (user && docSnap.exists()) {
        const data = docSnap.data()
        console.log(user.uid, user.email, user.displayName, data.lastname, data.title)
        console.log(data) // {lastname: 'sparrow', title: 'pirate'}
        dispatch(loginUser({
          userId: user.uid,
          firstName: user.displayName,
          lastName: data.lastname, //没有加载到Redux状态
          title: data.title, //没有加载到Redux状态
          email: user.email
        }))
      }
    } catch (error) {
      console.log(error.code)
    }
  })
})

// Redux
const initialState = {
  userId: null,
  firstName: null,
  lastName: null,
  title: null,
  email: null,
}

const userSlice = createSlice({
  name: "user",
  initialState,
  reducers: {
    loginUser: (state, action) => {
      state.userId = action.payload.userId
      state.firstName = action.payload.firstName
      state.lastName = action.payload.lastName
      state.title = action.payload.title
      state.email = action.payload.email
    },
    logoutUser: (state) => {
      state.userId = null
      state.firstName = null
      state.lastName = null
      state.title = null
      state.email = null
    },
  }
})

export const { loginUser, logoutUser } = userSlice.actions
export default userSlice.reducer
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

这是你提供的代码的翻译。

英文:

I am having an issue with Redux Toolkit not updating it's state for Firestore DB Subcollections. The Firebase Authentication fields work as Redux does update the userId, firstName(displayName), and email fields however the title and email fields which are from Firestore are not being updated. Any thoughts? Greatly appreciate it!

Please see below:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

//App.js
const dispatch = useDispatch();
useEffect(() =&gt; {
getAuth().onAuthStateChanged(async (user) =&gt; {
try {
const docRef = doc(db, &quot;users&quot;, user.uid)
const docSnap = await getDoc(docRef)
if (user &amp;&amp; docSnap.exists()) {
const data = docSnap.data()
console.log(user.uid, user.email, user.displayName, data.lastname, data.title)
console.log(data) // {lastname: &#39;sparrow&#39;, title: &#39;pirate&#39;}
dispatch(loginUser({
userId: user.uid,
firstName: user.displayName,
lastName: data.lastname, //not loading to redux state
title: data.title, // not loading to redux state
email: user.email
}))
}
} catch (error) {
console.log(error.code)
}
}
)})
//redux
const initialState = {
userId: null,
firstName: null,
lastName: null,
title: null,
email: null,
}
const userSlice = createSlice({
name: &quot;user&quot;,
initialState,
reducers: {
loginUser: (state, action) =&gt; {
state.userId = action.payload.userId
state.firstName = action.payload.firstName
state.lastName = action.payload.lastName
state.title = action.payload.title
state.email = action.payload.email
},
logoutUser: (state) =&gt; {
state.userId = null
state.firstName = null
state.lastName = null
state.title = null
state.email = null
},
}
})

export const { loginUser, logoutUser } = userSlice.actions
export default userSlice.reducer

<!-- language: lang-html -->

&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js&quot;&gt;&lt;/script&gt;

<!-- end snippet -->

答案1

得分: 1

根据Redux Toolkit的创建Redux状态切片文档,您还需要将每个切片函数导出为userSlice.actions,以及导出userSlice.reducer,然后按照以下方式将切片reducer添加到存储:

features/user/userSlice.js

import {
    createSlice
} from '@reduxjs/toolkit'
const initialState = {
    userId: null,
    firstName: null,
    lastName: null,
    title: null,
    email: null,
}
const userSlice = createSlice({
    name: "user",
    initialState,
    reducers: {
        loginUser: (state, action) => {
            const {
                userId,
                firstName,
                lastName,
                title,
                email
            } = action.payload;
            return {
                ...state,
                userId,
                firstName,
                lastName,
                title,
                email
            };
        },
        logoutUser: (state) => {
            state.userId = null
            state.firstName = null
            state.lastName = null
            state.title = null
            state.email = null
        },
    }
})

// Action creators are generated for each case reducer function
export const {
    loginUser,
    logoutUser
} = userSlice.actions
export default userSlice.reducer

app/store.js

import { configureStore } from '@reduxjs/toolkit'
import userReducer from '../features/user/userSlice'

export const store = configureStore({
  reducer: {
    user: userReducer,
  },
})

然后,在React组件中使用Redux状态和操作,就像您正在使用的方式一样。

正如您所说,您正在获取lastnametitle的firestore数据,但为了确认,您还可以像这样发送它们,以防这些字段为空。

const loginUserAction = {
  userId: user.uid,
  firstName: user.displayName,
  lastName: data.lastname || "", // ⇐ &#128072;
  title: data.title || "", // ⇐ &#128072;
  email: user.email
}
dispatch(loginUserAction)

更新:还要检查Redux Chrome扩展程序,以观察状态是否已更新。

参考:Redux Toolkit快速入门

英文:

According to the Create a Redux State Slice documentations from Redux Toolkit you also have to export each slice function as a userSlice.actions along with userSlice.reducer then Add the slice reducer to the store as follows :

features/user/userSlice.js

import {
createSlice
} from &#39;@reduxjs/toolkit&#39;
const initialState = {
userId: null,
firstName: null,
lastName: null,
title: null,
email: null,
}
const userSlice = createSlice({
name: &quot;user&quot;,
initialState,
reducers: {
loginUser: (state, action) =&gt; {
const {
userId,
firstName,
lastName,
title,
email
} = action.payload;
return {
...state,
userId,
firstName,
lastName,
title,
email
};
},
logoutUser: (state) =&gt; {
state.userId = null
state.firstName = null
state.lastName = null
state.title = null
state.email = null
},
}
})
// Action creators are generated for each case reducer function
export const {
loginUser,
logoutUser
} = userSlice.actions
export default userSlice.reducer

app/store.js :

import { configureStore } from &#39;@reduxjs/toolkit&#39;
import userReducer from &#39;../features/user/userSlice&#39;
export const store = configureStore({
reducer: {
user: userReducer,
},
})

Then use the Redux State and Actions in React Components just how you are using it.
As you have said that you are getting firestore data of lastname and title as intended.

But just for confirming you can also send those like this so if in case those fields happen to be null.

const loginUserAction = {
userId: user.uid,
firstName: user.displayName,
lastName: data.lastname || &quot;&quot;, // ⇐ &#128072;
title: data.title || &quot;&quot;, // ⇐ &#128072;
email: user.email
}
dispatch(loginUserAction)

Update: Also check the Redux chrome extension to observe whether the states are updated or not.

Reference : Redux Toolkit Quick Start

huangapple
  • 本文由 发表于 2023年6月5日 11:24:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76403328.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定