dappsnation / akita-ng-fire

Akita ❤️ Angular 🔥 Firebase
MIT License
131 stars 27 forks source link

this.fireAuth.auth.createUserWithEmailAndPassword is not a function #144

Closed jaytonic closed 3 years ago

jaytonic commented 4 years ago

Hi,

I've just followed most of your example + doc to setup the auth in my ionic project.

I've installed @angular/fire(6.0.2), akita-ng-fire(1.5.13), firebase(7.19.1), angular lib(10.0.0), ionic libs(5.0.0).

Here is my model:

export interface Profile {
  displayName: string;
  photoURL: string;
  organizationIds: string[];
}

export function createProfile(profile: Partial<Profile>): Profile {
  return {
    displayName: '',
    photoURL: '',
    organizationIds: [],
    ...profile,
  };
}

Here is my query:

import { Injectable } from '@angular/core';
import { Query } from '@datorama/akita';
import { AuthStore, AuthState } from './auth.store';

@Injectable({ providedIn: 'root' })
export class AuthQuery extends Query<AuthState> {
  profile$ = this.select('profile');
  userId$ = this.select((state) => state.profile.id);
  roles$ = this.select('roles');
  isLoggedIn$ = this.select((state) => !!state.profile); // check section "roles" below

  constructor(protected store: AuthStore) {
    super(store);
  }
}

Here is my store:

import { Injectable } from '@angular/core';
import {  Profile } from './auth.model';
import {  Store, StoreConfig } from '@datorama/akita';
import { FireAuthState, RoleState } from 'akita-ng-fire';

export interface AuthState extends FireAuthState<Profile>, RoleState {}

const initialState: AuthState = {
  uid: null,
  profile: null,
  roles: {},
  loading: false,
  emailVerified: false,
};

@Injectable({ providedIn: 'root' })
@StoreConfig({ name: 'auth' })
export class AuthStore extends Store<AuthState> {
  constructor() {
    super(initialState);
  }
}

And here is my service:

import { Injectable } from '@angular/core';
import { AuthStore, AuthState } from './auth.store';
import { CollectionConfig, FireAuthService } from 'akita-ng-fire';
import { createProfile } from './auth.model';

@Injectable({ providedIn: 'root' })
@CollectionConfig({ path: 'users' })
export class AuthService extends FireAuthService<AuthState> {
  formatFromFirestore = createProfile;

  constructor(store: AuthStore) {
    super(store);
  }

  onCreate() {
    console.log('Logged from onCreate hook');
  }

  onDelete() {
    console.log('Logged from onDelete hook');
  }

  onUpdate() {
    console.log('Logged from onUpdate hook');
  }

  onSignup() {
    console.log('Logged from onSignup hook');
  }

  onSignin() {
    console.log('Logged from onSignin hook');
  }

  onSignout() {
    console.log('You have been signed out. Logged from onSignout hook');
  }
}

I've set the environment's firebase + initialized firebase in my app.module.

But, when in my app, I'm trying to make a call to the service:

  async doLogin() {
    await this.authService.signup('aaa@bbb.com', 'xxxyyyzzz');
    await this.authService.signin('aaa@bbb.com', 'xxxyyyzzz');
  }

I get this error in chrome dev tools:


[WDS] Live Reloading enabled.
core.js:4197 ERROR Error: Uncaught (in promise): TypeError: this.fireAuth.auth.createUserWithEmailAndPassword is not a function
TypeError: this.fireAuth.auth.createUserWithEmailAndPassword is not a function
    at AuthService.<anonymous> (akita-ng-fire.js:1181)
    at Generator.next (<anonymous>)
    at tslib.es6.js:74
    at new ZoneAwarePromise (zone-evergreen.js:960)
    at __awaiter (tslib.es6.js:70)
    at AuthService.signup (akita-ng-fire.js:1179)
    at AppComponent.<anonymous> (app.component.ts:80)
    at Generator.next (<anonymous>)
    at tslib.es6.js:74
    at new ZoneAwarePromise (zone-evergreen.js:960)
    at resolvePromise (zone-evergreen.js:798)
    at zone-evergreen.js:705
    at rejected (tslib.es6.js:72)
    at ZoneDelegate.invoke (zone-evergreen.js:364)
    at Object.onInvoke (core.js:27436)
    at ZoneDelegate.invoke (zone-evergreen.js:363)
    at Zone.run (zone-evergreen.js:123)
    at zone-evergreen.js:857
    at ZoneDelegate.invokeTask (zone-evergreen.js:399)
    at Object.onInvokeTask (core.js:27424)

What could I've missed? What to do to initialize auth? I'm looking everywhere, but I can't find what I've missed.

I've dumped the this.authService before calling it, I'm seing a fireAuth property, but no auth below. Is there some kind of incompatibility?

fritzschoff commented 4 years ago

Why are you using version 1.5.13? The latest version is 3.0.4. try with that

jaytonic commented 4 years ago

Why are you using version 1.5.13? The latest version is 3.0.4. try with that

I didn't specify any version. it's what came when I did the NPM install. I upgraded, but now I've issues when running building:

[ng] ERROR in ./node_modules/akita-ng-fire/__ivy_ngcc__/fesm2015/akita-ng-fire.js 54:36-53
[ng] "export 'EntityStoreAction' was not found in '@datorama/akita'
[ng] ERROR in ./node_modules/akita-ng-fire/__ivy_ngcc__/fesm2015/akita-ng-fire.js 58:36-53
[ng] "export 'EntityStoreAction' was not found in '@datorama/akita'
[ng] ERROR in ./node_modules/akita-ng-fire/__ivy_ngcc__/fesm2015/akita-ng-fire.js 69:40-57
[ng] "export 'EntityStoreAction' was not found in '@datorama/akita'
[ng] ERROR in ./node_modules/akita-ng-fire/__ivy_ngcc__/fesm2015/akita-ng-fire.js 39:30-41
[ng] "export 'StoreAction' was not found in '@datorama/akita'
[ng] ERROR in ./node_modules/akita-ng-fire/__ivy_ngcc__/fesm2015/akita-ng-fire.js 44:30-41
[ng] "export 'StoreAction' was not found in '@datorama/akita'
[ng] ERROR in ./node_modules/akita-ng-fire/__ivy_ngcc__/fesm2015/akita-ng-fire.js 49:30-41
[ng] "export 'StoreAction' was not found in '@datorama/akita'
[ng] ERROR in ./node_modules/akita-ng-fire/__ivy_ngcc__/fesm2015/akita-ng-fire.js 54:4-24
[ng] "export 'runEntityStoreAction' was not found in '@datorama/akita'
[ng] ERROR in ./node_modules/akita-ng-fire/__ivy_ngcc__/fesm2015/akita-ng-fire.js 58:4-24
[ng] "export 'runEntityStoreAction' was not found in '@datorama/akita'
[ng] ERROR in ./node_modules/akita-ng-fire/__ivy_ngcc__/fesm2015/akita-ng-fire.js 69:8-28
[ng] "export 'runEntityStoreAction' was not found in '@datorama/akita'
fritzschoff commented 4 years ago

You need to have the latest akita version. Something above v5

jaytonic commented 4 years ago

You need to have the latest akita version. Something above v5

I'm sorry, I'm coming from the .Net word and a bit new to this package management. I tried to run npm update -g but the package hasn't been updated.

Isn't there any version dependencies? Why when I installed, i didn't got the last version?

Now it seems to work thank you!

One thing though: any reason why this selector: isLoggedIn$ = this.select((state) => !!state.profile); doesn't goes to true once I've logged in(I see the "Logged from onSignin hook")

jaytonic commented 4 years ago

@fritzschoff apparently, if I correctly understood, the formatFromFirestore of the service should call the createProfile of the model. but I've added some logs and still nothing, what is missing?

fritzschoff commented 4 years ago

You need to have the latest akita version. Something above v5

I'm sorry, I'm coming from the .Net word and a bit new to this package management. I tried to run npm update -g but the package hasn't been updated.

Isn't there any version dependencies? Why when I installed, i didn't got the last version?

there are peer dependencies. Not sure why you didn't saw that in your console. image

fritzschoff commented 4 years ago

@fritzschoff apparently, if I correctly understood, the formatFromFirestore of the service should call the createProfile of the model. but I've added some logs and still nothing, what is missing?

the formatFormFirestore calls what ever you want to be called. If you are talking about the AuthService in the example app. So you need to specify your own function in your project.

You can give your onSignin hook a paramter and work with the current logged in user. image

jaytonic commented 4 years ago

@fritzschoff I'm not sure I understand correctly:

If those 2 methods already exists, I guess it's because they are called by aktia-ng-fire, right?

Do you know if there is a working example somewhere with those user+profile? Because the FireAuthState already declare the profile and everything, so I would expect that it's updated automatically when method like signin/signout?

fritzschoff commented 4 years ago

image In the JSDocs you can see, that this function should be overriden. So you can specify what ever you want. But I will implement this function in the example app so you can see it

jaytonic commented 4 years ago

@fritzschoff That would be awesome, because I clearly see how I could implemented the method, but I don't where I should call it.

fritzschoff commented 4 years ago

in your service where you extend the FireAuthService<AuthState>

jaytonic commented 4 years ago

Yeah, but I don't understand, why all those methods/Store properties are defined if akita-ng-fire doesn't call them in the base classes?

Why not calling just before https://github.com/dappsnation/akita-ng-fire/blob/1a32f1e5282d5dc5d6a5d354ff2dfddb99f27676/projects/akita-ng-fire/src/lib/auth/auth.service.ts#L286

Something like: this.store.update({profile =formatFromFirestore(cred.user) }) (same for uid and emailVerified and this would have to be updated at other places, like signout, ...))

I'm maybe missing something, but I don't understand why it's the base class of the AuthStore that defines this profile, why it's the base service that defines those formatFromFirestore/... methods, but then suddently, it's the extension of the services that have to update the store value. I think it should be the responsability of the akita-ng-fire library(or the akita-ng-fire library should not have to declare those properties), because it causes an issue where you never know who(the base class or its extension) is responsible to update which part of the base AuthState.

I'm sorry if I don't speak very well, english isn't my first language.

fritzschoff commented 4 years ago

... english isnt my first language.

dont worry, mine neither. All good!

the base service defines these hooks like formatFromFirestore. So when you extend this base class you can override this hooks and work on the data like: switching from Javascript date into timestamp, for instance.

for the store loading stuff, this is what you need to do if you want to set the store in a loading state. So if the developer listens on the loading state of his store, he can show a spinner if the state is loading.

jaytonic commented 4 years ago

Yeah hooks are awesome, I don't argue about how usefull formatFromFirestore/toFirestore are usefull.

What I'm arguing is that this:

this.store.update({profile =formatFromFirestore(cred.user) })

should be in the base akita-ng-fire AuthService, it should not be required to call it from my extension of it. Don't you think?

fritzschoff commented 4 years ago

can you give an example how you want to alter the data if you don't want to call formatFromFirestore in your extension?

jaytonic commented 4 years ago

@fritzschoff But as you can see in my example: If you have this in your AuthService(not the extension) at this.store.update({profile =formatFromFirestore(cred.user) })

formatFromFirestore is still called, and in my extension I can decide to override this method(or not)

jaytonic commented 4 years ago

@fritzschoff another example:

When you signout, it's your class that manage to clear the profile in the store: https://github.com/dappsnation/akita-ng-fire/blob/82089c90824aeb4a9b00cbc348f721c4cecc260f/projects/akita-ng-fire/src/lib/auth/auth.service.ts#L300

But not on signin/signout(by the way, if I try to sign-in without having a sign-up first, I get an exception, so not sure when the cred.additionalUserInfo.isNewUser is true.

jaytonic commented 4 years ago

maybe it would be easier for me to do a PR for you to see what I mean?

fritzschoff commented 4 years ago

Yes, that would be good

jaytonic commented 4 years ago

Sorry, the autosave formated the page, but the important part is in the signin method of #146 I'm certainly missing one part of the issue

fritzschoff commented 4 years ago

I looked at your PR and will add some logic to the example app and test it. Should be done this afternoon CEST. Thanks for the PR !

fritzschoff commented 4 years ago

this.store.update(this.formatFromFirestore(cred.user)); this line for instance won't work since user has many keys that are not related to the store, like the key xa that has some cryptic stuff init. But I will make a PR for the other added update functions

fritzschoff commented 4 years ago

@jgrossrieder have a look at #147