vuex-easy-firestore icon indicating copy to clipboard operation
vuex-easy-firestore copied to clipboard

[NUXT] state._conf.sync.patchHook is not a function

Open ansidev opened this issue 6 years ago • 8 comments

Currently, I am experiencing this problem. I don't know why. Can you help me?

Problem

Uncaught (in promise) TypeError: state._conf.sync.patchHook is not a function
    at Store.patch (vendors.app.js:31896)
    at Array.wrappedActionHandler (commons.app.js:18004)
    at Store.dispatch (commons.app.js:17726)
    at Store.boundDispatch [as dispatch] (commons.app.js:17632)
    at local.dispatch (commons.app.js:17934)
    at Store.set (vendors.app.js:31813)
    at Array.wrappedActionHandler (commons.app.js:18004)
    at Store.dispatch (commons.app.js:17726)
    at Store.boundDispatch [as dispatch] (commons.app.js:17632)
    at Store.saveProfile (app.js:4904)

Code

// store/index.js
import Vuex from 'vuex'
import constant from "~/lib/constant"
import firebase from 'firebase/app'
import firestore from '~/plugins/firestore';
import VuexEasyFirestore from 'vuex-easy-firestore'

const userProfile = {
  firestorePath: 'users/{userId}',
  firestoreRefType: 'doc',
  moduleName: 'userProfile',
  statePropName: 'userProfile',
  sync: {
    // hooks for local changes:
    insertHook: function (updateStore, doc, store) { return updateStore(doc) },
    patchHook: function (updateStore, doc, store) { return updateStore(doc) },
    deleteHook: function (updateStore, id, store) { return updateStore(id) },
    insertBatchHook: function (updateStore, docs, store) { return updateStore(docs) },
    patchBatchHook: function (updateStore, doc, ids, store) { return updateStore(doc, ids) },
    deleteBatchHook: function (updateStore, ids, store) { return updateStore(ids) },
  },
}

const userProfileFirestore = VuexEasyFirestore(userProfile, {logging: true})

const getDefaultState = () => {
  return {
    locales: ['en', 'vi'],
    locale: constant.fallbackLocale,
    profile: null
  }
}

const createStore = () => {
  return new Vuex.Store({
    plugins: [userProfileFirestore],
    state: getDefaultState(),
    actions: {
      resetState({ commit }, $fiery) {
        return dispatch('userProfile/closeDBChannel')
      },
      loadProfile({ commit }, userId) {
        return dispatch('userProfile/set', {name: 'my new name'})
      },
      saveProfile({
        commit
      }, user) {
        let newUser = {
          displayName: user.firstName + ' ' + user.lastName || '',
          email: user.email,
          imageUrl: user.avatar || '',
          firstName: user.firstName,
          lastName: user.lastName,
          language: user.language || constant.fallbackLocale,
          isVerified: user.emailVerified || false,
          remember: user.rememberMe || false,
        }
        return this.dispatch('userProfile/set', newUser)
      },
      async userRegister({
        commit
      }, user) {
        try {
          const result = await firebase.auth()
            .createUserWithEmailAndPassword(user.email, user.password);
          this.dispatch('saveProfile', {
            firstName: user.firstName,
            lastName: user.lastName,
            ...result.user
          });
          this.dispatch('userSendVerificationEmail');
          $nuxt.$router.push(constant.routes.userReadingChecklist);
        }
        catch (error) {
          throw error;
        }
      },
      async userLogin({
        state
      }, account) {
        try {
          const result = await firebase.auth()
            .signInWithEmailAndPassword(account.email, account.password);
          this.dispatch('saveProfile', result.user);
        }
        catch (error) {
          throw error;
        }
      },
      async userLogout() {
        await firebase.auth()
          .signOut();
        this.dispatch('resetState');
        $nuxt.$router.push('/');
      },
      userSendVerificationEmail() {
        let currentUser = firebase.auth().currentUser;
        currentUser.sendEmailVerification()
          .then(function () {
            console.log("Sent verification email")
          })
          .catch(function (error) {
            console.log(error);
          });
      },
    },
  })
}

export default createStore

ansidev avatar Jan 01 '19 06:01 ansidev

Nothing wrong with this setup. When are you getting the error?

Also try deleting any hooks you do not use.

PS: Please note these other hints:

  1. you can add actions inside your userProfile
// add this under `actions` inside the module `userProfile`. Then it's more clear what data you are resetting
resetState({ dispatch }, $fiery) {
  return dispatch('closeDBChannel', {clearModule: true})
},
  1. add {clearModule: true} to closeDBChannel to actually reset the module data (see above)
  2. a lot of actions you pass {commit} as first parameter, while you use dispatch inside the action. Do not forget to add dispatch to the first param!!!
  3. Do not forget to add namespaced: true to your vuex-easy-firestore module to be able to use it with the module namespace!

--
Vuex Easy Firestore was made with ♥ by Luca Ban.
If this library helped you in any way you can support me by buying me a cup of coffee.

mesqueeb avatar Jan 01 '19 08:01 mesqueeb

The problem still there, do you have any working example for Vue or Nuxt?

ansidev avatar Jan 02 '19 04:01 ansidev

Hi @ansidev I wasn't able to program much the past two days. Sorry for the delayed response!!

I'm not sure what's wrong with your application. I myself have not worked with this library and Nuxt or server-side rendering yet.

If you can make a project folder in a zip or an online repository with the bug reproduced I can have a look!

Vuex Easy Firestore was made with ♥ by Luca Ban.
If this library helped you in any way you can support me by buying me a cup of coffee.

mesqueeb avatar Jan 03 '19 01:01 mesqueeb

Also see #66

Vuex Easy Firestore was made with ♥ by Luca Ban.
If this library helped you in any way you can support me by buying me a cup of coffee.

mesqueeb avatar Jan 03 '19 01:01 mesqueeb

You can clone this repository: https://github.com/SafeStudio/bible-reading-checklist. Currently, I make it work temporarily by using official Firebase API, you must replace it by vuex-easy-firestore API.

ansidev avatar Jan 03 '19 19:01 ansidev

@mesqueeb This problem is related to https://github.com/mesqueeb/vuex-easy-firestore/blob/ceed26107260e959197abd98f74ca55e1ebabbe6/src/module/index.ts#L21-L25.

After the above lines, the conf is the same as userConfig.

ansidev avatar Feb 09 '19 02:02 ansidev

@ansidev there's nothing wrong with that piece of code and i'm not sure what is causing your issue. I will look into your repository somewhere this weekend and let you know!

Btw, please remember that my library is not yet compatible with SSR or Nuxt. This is probably the cause of the problems.

Sent with GitHawk

mesqueeb avatar Feb 09 '19 02:02 mesqueeb

This is the result of console.log

defaultConfig

[Function]                                                                                                                                                             14:06:30
{                                                                                                                                                                      14:06:30
  firestorePath: '',
  firestoreRefType: '',
  moduleName: '',
  statePropName: '',
  logging: false,
  sync: {
    where: [],
    orderBy: [],
    fillables: [],
    guard: [],
    defaultValues: {},
    preventInitialDocInsertion: false,
    debounceTimerMs: 1000,
    insertHook: [Function: insertHook],
    patchHook: [Function: patchHook],
    deleteHook: [Function: deleteHook],
    insertBatchHook: [Function: insertBatchHook],
    patchBatchHook: [Function: patchBatchHook],
    deleteBatchHook: [Function: deleteBatchHook]
  },
  serverChange: {
    defaultValues: {},
    convertTimestamps: {},
    addedHook: [Function: addedHook],
    modifiedHook: [Function: modifiedHook],
    removedHook: [Function: removedHook]
  },
  fetch: {
    docLimit: 50
  }
}

userConfig

{                                                                                                                                                                      
  firestorePath: 'users/{userId}',
  firestoreRefType: 'doc',
  moduleName: 'userProfile',
  statePropName: 'userProfile',
  namespaced: true,
  actions: {
    saveProfile: [Function: saveProfile]
  },
  logging: true
}

conf

{                                                                                                                                                                     
  firestorePath: 'users/{userId}',
  firestoreRefType: 'doc',
  moduleName: 'userProfile',
  statePropName: 'userProfile',
  namespaced: true,
  actions: {
    saveProfile: [Function: saveProfile]
  },
  logging: true
}

ansidev avatar Feb 09 '19 07:02 ansidev