0

I'm trying to update af user's profile with updateProfile()

When I call the function exactly as the example from the link above, it throws the TypeError: currentUser.updateProfile is not a function. I tried to console.log() the user and weirdly it does not show the updateProfile() function.

I'm using the user retrieved from auth.onAuthStateChanged(). I then uses Firebase firestore where I store other user info. I merges that user object with the data retrieved from firestore with:

const mergedUser = Object.assign({}, user, doc.data())

I pass mergedUser to a useState() currentUser that is passed to my context provider value.

Everything else works, but the functions that is supposed to be on the userobject is not present after the Object.assign(). How could merge the user object so I can access all userdata AND the firebase user functions, such as updateProfile()

Thank you in advance!

package.json:

{
  "name": "planom",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  },
  "dependencies": {
    "firebase": "^8.2.7",
    "next": "10.0.6",
    "react": "17.0.1",
    "react-dom": "17.0.1",
    "sass": "^1.32.7"
  },
  "devDependencies": {}
}
idkwhatsgoingon
  • 658
  • 4
  • 22

2 Answers2

2

Object.assign copies all enumerable properties (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign). However, this doesn't include non-enumerable properties (like prototype methods).

I can think of a few different solutions:

Use firebase.auth().currentUser

firebase.auth().currentUser is already available in the global scope, so you could access the methods that way

Restructure your state

Instead of trying to combine user and doc.data(), make them different properties of a new object. Eg:

{
  user: user,
  userData: doc.data()
}

(The downside here is that you're still trying to store a complex object with methods in state -- not ideal if relying on a state that gets rehydrated, for example)

Use Object.create? Maybe?

Personally, I wouldn't mess around with this system if I were you, as the first two are much simpler and more reliable if the underlying API changes, but you could try to use Object.create and then Object.assign to create an object that did have the original methods available. See this answer: Using Object.assign and Object.create for inheritance

jnpdx
  • 45,847
  • 6
  • 64
  • 94
0

Make sure that your link to your js-file bellow ALL other firebase script imports. Your error is quite common if you link them in the wrong order, also don't forget to defer the script tag if you link to your script in your header.

<script src="myJS.js" defer></script>

Defer makes sure that the js document is read after the HTML, and if you copied your firebase js-imports, they're also deferred.

FoxPaw
  • 186
  • 1
  • 9