Binding data to user (firebase) - javascript

So I have created working user authentication, and a page which contains 3 inputs and a “create user” button.
The data form inputs is pushed to firebase, but I don’t think it is binded to the logged user.
here is code:
export class ProfilePage {
profileData: AngularFireObject<Profile>
profile = {} as Profile;
constructor(private afAuth: AngularFireAuth, private afDatabase: AngularFireDatabase,
public navCtrl: NavController, public navParams: NavParams) {
}
ionViewDidLoad() {
console.log('ionViewDidLoad ProfilePage');
}
createProfile() {
this.afAuth.authState.take(1).subscribe(auth => {
this.afDatabase.object(`profile/${auth.uid}`).set(this.profile)
.then(() => this.navCtrl.setRoot(MainPage));
})
}
}
the data on firebase looks like this:

With your data structure, here is the "standard" javascript code to get the data for the current user:
var userId = firebase.auth().currentUser.uid;
return firebase.database().ref('/bike-it-app/profile/' + userId).once('value').then(function(snapshot) {
var firstname = snapshot.val().firstname;
var lastname = snapshot.val().lastname;
var username = snapshot.val().username;
// ...
});
Note that here we use "once". You could alternatively use "on", depending on your requirements, see https://firebase.google.com/docs/database/web/read-and-write#listen_for_value_events

Related

Reload a component from another component

I was trying to reload a component using the below code
reload() {
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
this.router.onSameUrlNavigation = 'reload';
this.router.navigate(['/'], { relativeTo: this.route, queryParamsHandling: 'preserve' });
}
But in a service file, I was using the below block of code in a service file to get query params
constructor(
private route: ActivatedRoute,
private generalSettings: GeneralSettingsService,
private httpClient: HttpClientService,
private toastrService: ToastrService,
) {
this.route.queryParams.subscribe(params => {
this.module = params['module'];
this.env = params['env'];
console.log(this.module, this.env)
});
}
Once I reload the component, I am not able to get the query params.

I want to make a query based on the current logged in user id in Angular using firebase as my back-end

I've created a bookmarking feature which if the users clicks at the bookmark button the user's id will be save to that documents bookmark array in firebase which is working fine.
But i want to show all bookmarks by a user in the bookmark page/tab (it's a news site btw the documents have title, picture, article, bookmarks and so on kind of data).
I've got it to work manually
bookmarks$: Observable<lajmiId[]>;
bookmarksBehaviorSubject : BehaviorSubject<string|null>;
constructor(
private afs: AngularFirestore,
public authService: AuthService,
private ls: LoginService) {
this.bookmarksBehaviorSubject = new BehaviorSubject(null);
this.bookmarks$ = this.bookmarksBehaviorSubject.pipe(
switchMap(string => this.afs.collection<lajmiId>('lajmet', ref =>
ref.where('bookmarks', 'array-contains', 'manually_written_uid')).valueChanges())
);
}
Which works however when i try to pas in the uid dynamically based on the current logged in user it's not working,
var uid = this.authService.userData.uid;
this.bookmarksBehaviorSubject = new BehaviorSubject(null);
this.bookmarks$ = this.bookmarksBehaviorSubject.pipe(
switchMap(string => this.afs.collection<lajmiId>('lajmet', ref =>
ref.where('bookmarks', 'array-contains', uid)).valueChanges())
);
This gives me an error of undefined since it's trying to read the uid before the data is ready to be used since the data is asynchronous.
I've tried putting the code in the ngOnInit() block same result.
I've tried creating an observable with the uid data still same result.
i just can't seem to figure this out.
My authServise looks something like this:
import { User } from '../core/user';
export class AuthService {
userData: Observable<any>;
constructor(
public afs: AngularFirestore, // Inject Firestore service
public afAuth: AngularFireAuth, // Inject Firebase auth service
public router: Router,
public ngZone: NgZone, //ngZone service to move outside scope warning
private dialogRef: MatDialog
) {
this.afAuth.authState.subscribe(user => {
if (user) {
this.userData = user;
localStorage.setItem('user', JSON.stringify(this.userData));
JSON.parse(localStorage.getItem('user'));
}
})
}
}
My User.ts contains the User interfase.
Any help is much appreciated.
In your auth service you need to make the user as an Observable and then you can easily subsribe it on ngOnInit.
Suppose your auth.service.ts
export class AuthService{
user$:Observable<any>;
constructor(private router: Router,
private afAuth: AngularFireAuth,
private db:AngularFirestore,
) {
this.user$ = this.afAuth.authState.pipe(
switchMap(user => {
if (user) {
//here you get the logged in user cred like uid
//you can use uid to refer in your collection
return this.afs.collection<lajmiId>(`lajmet/${user.uid}`).valueChanges()
} else {
return of(null)
}
})
)
}
}
This will always give you the current logged in user and then you can easily subscribe after importing your authservice in the component you are trying to fetch.
this.authService.user$.take(1).subscribe(data=>{
//data of the user logged in
})

Angular 5 show data from firebase nodes

i need a bit of help.
I am trying to display data from specific loged in user but i have a hard time.
in html :
<div *ngFor="let to of UnData">
TS:
export class something {
todo: AngularFireList<any>;
UnData = [];
userId: string;
constructor(public navCtrl: NavController, public navParams: NavParams, private db: AngularFireDatabase, private fire: AngularFireAuth) {
this.fire.authState.subscribe(user =>{
if(user) this.userId = user.uid
});
if (!this.userId) return;
this.db.list("people/${this.userId}").valueChanges().subscribe(_data => {
this.UnData = _data;
console.log(this.UnData);
});
}
console.log gives me nothing in return. I think i am doing something wrong in code where i am getting data from database. Please give me a bit of help :-)
Thanks Frank,
the first problem was backticks but i still had problems and solved and important part was ngOnInit(userId:string):
export class something {
todo: AngularFireList<any>;
unData = [];
userId: string;
title: string;
desc: string;
constructor(public navCtrl: NavController, public navParams: NavParams, private db: AngularFireDatabase, private fire: AngularFireAuth) {
this.fire.authState.subscribe(user => {
if (user) {
this.userId = user.uid;
console.log(this.userId);
}
});
}
postDatatoDB(title: string, desc: string, userId: string): void {
this.db.list("/tasks/" + this.userId).push({ title: title, desc: desc });
this.title = '';
this.desc = '';
}
**ngOnInit(userId:string)** {
this.db.list<any>(`/tasks/${this.userId}`).valueChanges().subscribe(data => {
this.unData = data;
console.log(this.unData);
});
}
}

Angular - Data is loaded - Initial value of ID is NaN

On my web-app written in angular I am posting data to a Database and I am displaying this data in a table on the same html. Each data record has an ID. And every time I am adding new data, the ID is going to be increased. The first input field shows the actual ID, see the screenshot below:
In my ngOnInit-method I am initialising the id and I call the function fbGetData() in order to display the data.
But now I am facing one odd problem:
Everytime I starting the application the initial value which is displayed in the ID-field is NaN.
Obviously I cannot post any data to the database because the ID is not a number. So I have to switch to another page on my application and then switch back. After that the correct ID is displayed. I also tried to move my methods from the ngOnInit-method to the constructor but this didn't help.
Somehow I think that I need to implement the methods asynchronously, but I have no idea how to do this, since I am quite new to Angular/Typscript.
I hope you guys can help me with this problem or give me any hint or idea.
I appreciate your answers!
Here is my .ts Code:
import { Component, OnInit, ViewEncapsulation } from '#angular/core';
import { Router, ActivatedRoute, Params } from '#angular/router';
import { DataService } from '../data.service';
import { Http } from '#angular/http';
import { rootRoute } from '#angular/router/src/router_module';
import { SearchNamePipe } from '../search-name.pipe';
import { LoginComponent } from '../login/login.component';
import {NavbarService} from '../navbar.service';
declare var firebase: any;
const d: Date = new Date();
#Component({
selector: 'app-business-function',
templateUrl: './business-function.component.html',
styleUrls: ['./business-function.component.css'],
encapsulation: ViewEncapsulation.None,
providers: [DataService, SearchNamePipe, LoginComponent]
})
export class BusinessFunctionComponent implements OnInit {
id;
name: String;
descr: String;
typ: String;
bprocess: String;
appsystem: String;
applications: String;
datum: String;
liste = [];
bprocessliste = [];
applicationliste = [];
appsystemliste = [];
isDesc: boolean = false;
column: String = 'Name';
direction: number;
loginName: String;
statusForm: Boolean = false;
private idlist = [];
constructor(
private dataService: DataService,
private router: Router,
private route: ActivatedRoute,
private searchName: SearchNamePipe,
private navbarService: NavbarService
) {
this.datum = Date().toString();
}
ngOnInit() {
this.navbarService.show();
firebase.database().ref().child('/AllID/').
on('child_added', (snapshot) => {
this.idlist.push(snapshot.val()
)})
this.id = this.idlist[0];
console.log("ID: "+this.id);
console.log("IDlist: "+this.idlist[0]);
this.id++;
console.log("ID: "+this.id);
this.fbGetData();
}
fbGetData() {
firebase.database().ref().child('/BFunctions/').orderByChild('CFlag').equalTo('active').
on('child_added', (snapshot) => {
//firebase.database().ref('/BFunctions/').orderByKey().on('child_added', (snapshot) => {
// alter code ... neuer Code nimmt nur die Validen mit dem X Flag
this.liste.push(snapshot.val())
});
// firebase.database().ref().child('/ID/').on('child_added', (snapshot) => {
//Bprocess DB Zugriff
firebase.database().ref().child('/BProcess/').orderByChild('CFlag').equalTo('active').
on('child_added', (snapshot) => {
this.bprocessliste.push(snapshot.val())
});
//Appsystem DB Zugriff
firebase.database().ref().child('/Appsystem/').orderByChild('CFlag').equalTo('active').
on('child_added', (snapshot) => {
this.applicationliste.push(snapshot.val())
})
//Application DB Zugriff
firebase.database().ref().child('/Application/').orderByChild('CFlag').equalTo('active').
on('child_added', (snapshot) => {
this.applicationliste.push(snapshot.val())
});
console.log(this.applicationliste);
}
You need to update the id inside your callback:
firebase.database().ref().child('/AllID/').on('child_added', (snapshot) => {
this.idlist.push(snapshot.val())
this.id = this.idlist[0];
console.log("ID: "+this.id);
console.log("IDlist: "+this.idlist[0]);
this.id++;
console.log("ID: "+this.id);
this.fbGetData();
})
Otherwise id retains it initial undefined value. This is because the call to firebase is asynchronous.
Here is what happens in your original code:
call to firebase API... wait your response
set id to this.idlist[0], which is empty (undefined)
...some time later, getting response from firebase
id does not get updated because the code in point 2. has already been executed.
Anything that you need to do when you get the result from an asynchronous call, must be executed inside the callback function.

Angular 4 firebase read a value from database and pass it to the program

I am using Angular 4 and angularfire with Firebase database.I have the following Firebase database
"questions" : {
"tv" : {
"got" : {
"1" : {
"answer1" : "Death",
"choice11" : "Exile",
"choice12" : "You lose a hand",
"choice13" : "You lose the privilege to marry and father children",
"description" : "",
"q1title" : "What is the punishment for deserting the Night’s Watch?"
},
"questions" : {
"number" : 1
}
}
}
}
And I want to read the question number on the button and pass it to my program to use it on functions etc.I am currently using this part of code to read it
constructor(public afAuth: AngularFireAuth, public af: AngularFireDatabase,public authService: AuthService,
private router: Router) {
var ref = firebase.database().ref("questions/tv/got/questions");
ref.once("value")
.then(function(snapshot) {
let qnumber = snapshot.child("number").val();
console.log(qnumber);
});
}
Everything works fine and I can see the qnumber on the concole(qnumber=1).However I can't pass the qnumber on the program and use it for my other functions
I tried to declare a second variable like and give it the qnumber value like this
qnumber2;
constructor(public afAuth: AngularFireAuth, public af: AngularFireDatabase,public authService: AuthService,
private router: Router) {
var ref = firebase.database().ref("questions/tv/got/questions");
ref.once("value")
.then(function(snapshot) {
let qnumber = snapshot.child("number").val();
this.qnumber2 = qnumber;
console.log(qnumber2);
});
But I get errors on compiler.Can you help me and tell my a way to pass the qnumber on my program as an integer?
Try this :
qnumber2;constructor(public afAuth: AngularFireAuth, public af: AngularFireDatabase,public authService: AuthService,
private router: Router) {
var ref = firebase.database().ref("questions/tv/got/questions");
ref.once("value")
.then((snapshot) => {// ** My only change ** or use snapshot
let qnumber = snapshot.child("number").val();
this.qnumber2 = qnumber;
console.log(qnumber2);
});
The this keyword refers to the object the function belongs to, or
the window object if the function belongs to no object.In JavaScript a function is an object.
for more on this inside a function
In your case this.qnumber2 is not the global one , it's scope is limited to the function it is used. If you don't use any function then this will refer to the global object.

Categories

Resources