[SOLVED] After unsubscribe calls permission denied error


#1

Hello folks.
I have a weird permission denied issue after fully unsubscribing from all my pages.
It works perfectly fine on a real device but not on the Chrome browser.
I’ve looked at the logs and it seems like the problem starts from Username.ts file but, still getting an error.

Page starts from SettingPage -> ProfileDetailPage -> UsernamePage (No keyup event calls from checkUsername() then no problem to log out.)
After I saveUsername from UsernamePage and try to make an attempt to log out from SettingPage then it throws an error. :frowning:

Here’s the code looks like.

Username.ts

export class UsernamePage implements OnDestroy {
  private subscription: Subscription;
  private currentUsername: string;
  private usernameText: string;
  private isUsernameAvailable: boolean;
  private hasSetUsername: boolean = false;

  constructor(
    public navCtrl: NavController,
    public navParams: NavParams,
    private userService: UserServiceProvider) {
    this.currentUsername = this.navParams.get('username');
  }

  saveUsername() {
    this.hasSetUsername = true;
    this.userService.removeDeprecatedUsername(this.currentUsername);
    this.userService.updateUsername(this.usernameText);
    this.currentUsername = this.usernameText;
  }

  checkUsername() {
    this.subscription = this.userService.checkUsername(this.usernameText).subscribe(username => {
      if (username !== null)
        this.isUsernameAvailable = false;
      else
        this.isUsernameAvailable = true;
    });
  }

  ngOnDestroy() {
    if (this.subscription !== undefined) {
      this.subscription.unsubscribe();
      console.log("Username ngOnDestroy");
    }
  } 
}
<ion-buttons right>
        <button ion-button color="dark" (click)="saveUsername()">
            SAVE
        </button>
    </ion-buttons>

<ion-content padding>
<ion-input type="text" placeholder="Letters or Letters with numbers ONLY" [(ngModel)]="usernameText" (keyup)="checkUsername()"></ion-input>
</ion-content>

profile-detail.ts

export class ProfileDetailPage implements OnDestroy {
  private subscription: Subscription;
  private previewImage: any;
  private avatar: string;
  private displayName: string;
  private username: string;
  private gender: string;
  private user: any[];

  @ViewChild('genderMale', {read: ElementRef}) maleButton;
  @ViewChild('genderFemale', {read: ElementRef}) femaleButton;

  constructor(
    public navCtrl: NavController,
    public navParams: NavParams,
    public actionSheetCtrl: ActionSheetController,
    public viewCtrl: ViewController,
    private renderer: Renderer,
    private camera: Camera,
    private userService: UserServiceProvider,
    private uploadService: UploadServiceProvider,
    private loadingService: LoadingServiceProvider) {

    this.getUserProfile();
  }

  getUserProfile() {
    this.subscription = this.userService.getCurrentUser().subscribe((user: any) => {
      console.log("Current user:", user);
      this.avatar = user.photoURL;
      this.displayName = user.displayName;
      this.gender = user.gender;
      this.username = user.username;
    });
  }

  ngOnDestroy() {
    if (this.subscription !== undefined) {
      this.subscription.unsubscribe();
      console.log("ProfileDetail ngOnDestroy");
    }
  }

setting.ts

export class SettingPage implements OnDestroy {
  private subscription: Subscription;
  private username: string;

  constructor(
    public navCtrl: NavController,
    public navParams: NavParams,
    private authService: AuthServiceProvider,
    private userService: UserServiceProvider,
    private toastService: ToastServiceProvider,
    private modalService: ModalServiceProvider,
    private uploadService: UploadServiceProvider) { }

 
  ionViewWillEnter() {
    this.subscription = this.userService.getCurrentUsername().subscribe((user: any) => {
      console.log("SettingPage user", user);
      this.username = user;
    });
  }

  ngOnDestroy() {
    if (this.subscription !== undefined) {
      this.subscription.unsubscribe();
      console.log("Setting ngOnDestroy");
    }
  }
  async logout() {
    this.userService.updateCurrentActiveStatusTo(false);
    const user: any = await this.authService.signOut();
    this.toastService.show(`Signed out as ${user.email}`);
  }
}

cli packages: (/usr/local/lib/node_modules)

@ionic/cli-utils  : 1.19.0
ionic (Ionic CLI) : 3.19.0

global packages:

cordova (Cordova CLI) : 7.1.0

local packages:

@ionic/app-scripts : 3.1.4
Cordova Platforms  : android 6.3.0
Ionic Framework    : ionic-angular 3.9.2

System:

Node  : v8.9.0
npm   : 5.5.1
OS    : OS X El Capitan

#2

Added take operator and the issue has vanished.

checkUsername() {
    this.subscription = this.userService.checkUsername(this.usernameText).take(1).subscribe(username => {
      if (username !== null)
        this.isUsernameAvailable = false;
      else
        this.isUsernameAvailable = true;
    });
  }