将嵌套集合包含到 firebase.profile

Include nested collections to firebase.profile

我目前正在开发 React / Redux / Firebase 应用程序。

在我的 Firebase Cloud Firestore 我存储用户数据,在创建 Auth 用户后动态创建。

在我的 index.js 中,我使用 useFirestoreForProfile: true 来获取相应的用户数据以显示在 firebase.profile

index.js

const store = createStore(rootReducer,
    compose(
        applyMiddleware(
            thunk.withExtraArgument({
                getFirebase, // Firebase
                getFirestore // Cloud Database
            })
        ),
        reduxFirestore(fbInit),
        reactReduxFirebase(fbInit, {
            useFirestoreForProfile: true, // Sync user data to firebase.profile
            userProfile: 'users', // Tell Redux Firebase where our users are stored
            attachAuthIsReady: true // Enable firebase initializing before DOM rendering
        })
    )
);

我的身份验证操作:

/store/actions/authActions.js

export const signIn = (credentials) => {
    return (dispatch, getState, {getFirebase}) => {
        const firebase = getFirebase();

        firebase.auth().signInWithEmailAndPassword(
            credentials.email,
            credentials.password
        ).then(() => {
            dispatch({
                type: 'LOGIN_SUCCESS'
            })
        }).catch((err) => {
            dispatch({
                type: 'LOGIN_ERROR',
                err
            })
        });
    }
}

我的身份验证reducer中成功登录的部分:

/store/reducers/authReducer.js

  case 'LOGIN_SUCCESS':
      console.log('Login success');
      return {
         ...state,
         authError: null,
         authErrorDetails: null
      };

我将状态映射到组件道具的方式:

/components/pages/Dashboard/index.jsx

const mapStateToProps = (state) => {
    console.log(state);
    return {
        records: state.firestore.ordered.records,
        tabs: state.firestore.ordered.tabs,
        auth: state.firebase.auth,
        profile: state.firebase.profile
    }
}

当前的配置文件数据如下所示:

在设置了这些字段的用户文档中,我创建了一个附加集合

路径看起来像:users -> (document id) -> tabs -> (document id) -> fields

有什么方法可以将选项卡集合包含在 firebase.profile


最终对象应该类似于我刚刚 手动创建 用于显示目的的对象:

有办法实现吗?我真的希望它只是缺少一个参数或其他东西。

对单个集合(或者如果您使用 collection group queries)同名集合中的 Firestore returns 文档的任何读取操作。无法像在数据模型中那样深入查询嵌套集合。在您的模型中,您需要对来自 users 的文档和来自 tabs.

的文档进行单独的读取操作

除此之外,很难说出您具体需要做什么,因为我不知道 useFirestoreForProfile 是什么以及您显示的 profile 对象代表什么。

我已经通过在用户字段中创建一个数组解决了这个问题。

export const createTab = (tab) => {
    return (dispatch, getState, { getFirebase, getFirestore }) => {
        // Make aync call to DB

        // Get userId (to know where to store the new tab)
        const userId = getState().firebase.auth.uid;
        // Get user tabSlots to decide how many tabs the user may have
        const userTabSlots = getState().firebase.profile.tabSlots;
        // Get current tabs (to not overwrite)
        const currentTabs = getState().firebase.profile.tabs;

        // Check if already exists
        let exists = currentTabs.map((ctab, i) => {
            if(ctab.title === tab.title){
                dispatch({ type: 'CREATE_TAB_ERROR_DUPLICATE', err: "Duplicate" });
                return true;
            } else {
                return false;
            }
        });

        // Check if the user can make new tabs dependent on the tier
        let canCreate = true;
        if(currentTabs.length === userTabSlots){
            dispatch({ type: 'CREATE_TAB_ERROR_LIMIT', err: "Tab limit reached" });
            canCreate = false;
        }

        // If it does not already exists and user can create new tabs
        if(!exists.includes(true) && canCreate){
            const firestore = getFirestore();
            firestore.collection('users').doc(userId).update({
                tabs: [
                    ...currentTabs,
                    {...tab, createdAt: new Date()} 
                ]
            }).then(() => {
                dispatch({ type: 'CREATE_TAB', tab });
            }).catch((err) => {
                dispatch({ type: 'CREATE_TAB_ERROR', err });
            })
        }
    }
}