[SOLVED] User().profile field missing on Accounts.createUser()


#1

.profile field is not registering, when signing up with password. (Accounts.createUser() )

Any idea what could be causing this?
When signing up with Facebook, everything works fine below are code snippets from both cases.

Also please feel free to comment if you have any suggestions regarding the provided code to an aspiring Meteor dev :slight_smile:

import React, { Component } from "react";
import { Accounts } from "meteor/accounts-base";
import { withApollo } from "react-apollo";
import withRouter from "react-router-dom/withRouter";
import FacebookLogin from "./FacebookLogin";

class SignUpForm extends Component {
   // .. code emitted 

  handleSignUpClick = () => {
    const email = this.email.value;
    const password = this.password.value;
    const firstName = this.firstName.value;
    const lastName = this.lastName.value;

    Accounts.createUser(
      {
        email,
        password,
        // .. code emitted 
        profile: {
          firstName,
          lastName
        }
      },
      error => {
        if (error) {
          this.setState({ hasError: true, errorMessage: error.reason });
        } else {
          this.props.history.push(`/`);
          this.props.client.reFetchObservableQueries();
        }
      }
    );
  };

  render() {
    const { dob } = this.state;
    const { history, client } = this.props;
    return (
      <>
        <FacebookLogin client={client} history={history} />
        <input
          placeholder="First Name"
          ref={input => (this.firstName = input)}
        />
        // .. code emitted 
        <input
          type="email"
          placeholder="Email Address"
          ref={input => (this.email = input)}
        />
        <input
          type="password"
          placeholder="Password"
          ref={input => (this.password = input)}
        />
        <button type="submit" onClick={this.handleSignUpClick}>
          Sign Up
        </button>
      </>
    );
  }
}

export default withApollo(withRouter(SignUpForm));


FACEBOOK LOGIN

import React from "react";

export default ({ history, client }) => {
  handleFacebookLogin = e => {
    e.preventDefault();

    Meteor.loginWithFacebook(
      { requestPermissions: ["public_profile", "email"] },
      function(err) {
        if (err) {
          console.log("Handle errors here: ", err);
        } else {
          client.reFetchObservableQueries();
          history.push(`/`);
        }
      }
    );
  };
  return (
    <button onClick={handleFacebookLogin} >
      Continue with Facebook
    </button>
  );
};

And the Accounts.onCreateUser:

Accounts.onCreateUser((options, user) => {
  if (!user.services.facebook) {
    return user;
  }

  const { facebook } = user.services;

  // .. 
  user.emails = [{ address: facebook.email, verified: false }];
  user.profile = {
    about: "",
    firstName: facebook.first_name,
    lastName: facebook.last_name,
    // .. 
    picture: `http://graph.facebook.com/` + facebook.id + "/picture/?width=400"
  };

  return user;
});

EDIT:
This is what the resulting user object looks like:

{ 
    "_id" : "4DrHj2u63FXWKDioi", 
    "createdAt" : ISODate("2018-10-08T23:12:49.094+0000"), 
    "services" : {
        "password" : {
            "bcrypt" : "$2b$777777777777777"
        }, 
        "email" : {
            "verificationTokens" : [
                {
                    "token" : "777777777777777", 
                    "address" : "scott@example.com", 
                    "when" : ISODate("2018-10-08T23:12:49.102+0000")
                }
            ]
        }, 
        "resume" : {
            "loginTokens" : [
                {
                    "when" : ISODate("2018-10-08T23:12:49.438+0000"), 
                    "hashedToken" : "7777777777777777777777="
                }
            ]
        }
    }, 
    "emails" : [
        {
            "address" : "scott@example.com", 
            "verified" : false
        }
    ]
}


#2

In your onCreateUser() function, you’re only returning the user object if he is not logging from facebook. The profile is in the options object, as is every custom field you may add when calling createUser().
Also, and I hope you’ll take that with humor as it’s meant that way, but an advise I’d give to a learning developer is to read the doc :smiley: It’s all in there, for that specific question :wink:


#3

This is what I was missing! Thank you, bud!

For those interested – solution below:

As a newbie, in the very early lines of my app I had followed a specific tutorial for loginWithFacebook, and it had the following line:

if (!user.services.facebook) {
    return user;
  }

Many more code lines down the road, I had forgotten about this.

The issue is that these lines return plain user, if user is created with services.facebook, hence the rest of the data from the Accounts.createUser() (on client in my case) is not being passed.

The solution quite simple as pointed out by @pdecrat:

if (!user.services.facebook) {
    user.somefield = "someStringData";
    user.someOtherfield = someAssignVariableData;
    user.emails = [{ address: email, verified: false }];
    user.profile = {
      firstName,
      lastName
    };
    return user;
  }

Just thought that perhaps a bit more elaborate explanation could come in handy for someone.

Thank you @pdecrat for pointing this out!