I have a database from firebase. I want to retrieve some data using a user's email. suppose user put his/her email if the email exists in the firebase database then it shows his/her username and password. I am not using firebase authentication, I am using firebase realtime database.
here is my database structure:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_forgate_password);
emailf = findViewById(R.id.emailf);
userf = findViewById(R.id.usernamef);
passwordf = findViewById(R.id.passwordf);
ok = findViewById(R.id.okbtn);
database = FirebaseDatabase.getInstance();
users = database.getReference("Users").child("emailAddress");
ok.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
signInMethod(emailf.getText().toString());
}
});
}
private void signInMethod(final String email) {
users.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
if (dataSnapshot.child("emailAddress").exists()){
if (dataSnapshot.child(user.getUserName()).exists()){
Toast.makeText(ForgatePassword.this,"User already exists",Toast.LENGTH_LONG).show();
}
}
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w("Tag", "Email not exists", error.toException());
}
});
}
here is my model class:
public class SignInUpModel {
private String fullName;
private String userName;
private String schoolName;
private String className;
private String division;
private String phnNumber;
private String emailAddress;
private String reference;
private String password;
public SignInUpModel() {
}
public SignInUpModel(String fullName, String userName, String schoolName, String className, String division, String phnNumber, String emailAddress, String reference, String password) {
this.fullName = fullName;
this.userName = userName;
this.schoolName = schoolName;
this.className = className;
this.division = division;
this.phnNumber = phnNumber;
this.emailAddress = emailAddress;
this.reference = reference;
this.password = password;
}
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getSchoolName() {
return schoolName;
}
public void setSchoolName(String schoolName) {
this.schoolName = schoolName;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getDivision() {
return division;
}
public void setDivision(String division) {
this.division = division;
}
public String getPhnNumber() {
return phnNumber;
}
public void setPhnNumber(String phnNumber) {
this.phnNumber = phnNumber;
}
public String getEmailAddress() {
return emailAddress;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
public String getReference() {
return reference;
}
public void setReference(String reference) {
this.reference = reference;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
How can I do this?
Using firebase database to create your own authentication system is not a good idea.
What you want to do will require you to allow read of every user's email password stored in database. This will be a huge security risk for your app as anyone can read all the email passwords in your database.
Firebase provides easy to use firebase authentication with many options to use. You can easily delegate the security to firebase auth and store your user's profile and data in db. This way you can also restrict data access for each user (which is why you want email password login for your app).
Please see the authentication documents of firebase: https://firebase.google.com/docs/auth
It will help you create your app without implementing your own auth and focus on actual features development.
Related
I developed a login app in Java where the user can login using their emailaddress and password. This works fine so far, but I have the problem that my UserModel.java is null when I get to my home activity. This also makes sense to me since Firebase Auth only checks the email and password and does not select the relevant information from the realtime database. I have therefore inserted a datasnapshot, this also works in the intended way since the system outputs the desired name.
My question is now how can I assign this datasnapshot to my UserModel so that my UserModel is no longer null (is it?!). In the last part of my HomeActivity you can see a String which should contain the Users Name, however even if I log in with an existing account this String is only showing the "Example Name". Due to the fact that the system is printing out the correct name I believe the DataSnapshot works as it should.
Thanks for your help!
part of my HomeActivity
firebaseAuth = FirebaseAuth.getInstance();
firebaseDatabase = FirebaseDatabase.getInstance();
final FirebaseDatabase database =FirebaseDatabase.getInstance();
DatabaseReference myref=database.getReference("Users").child(firebaseAuth.getUid());
myref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
UserModel userModel= dataSnapshot.getValue(UserModel.class);
System.out.println(userModel.getName());
currentUser=userModel;
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(HomeActivity.this, ""+databaseError.getCode(), Toast.LENGTH_SHORT).show();
}
});
if(currentUser!=null) {
Common.setSpanString("Hey, ", currentUser.getName(), txt_user);
}
else{
UserModel userModel = new UserModel(uid,name,address,phone,email,password);
userModel.setName("Example Name");
Common.setSpanString("Hey, ", userModel.getName(), txt_user);
}
UserModel
private String uid, name, address, phone, email, password;
public UserModel() {
}
public UserModel(String uid, String name, String address, String phone,String email,String password) {
this.uid = uid;
this.name = name;
this.address = address;
this.phone = phone;
this.email = email;
this.password = password;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() { return password; }
public void setPassword(String password) {
this.password = password;
}
}
part of my Common class
public static UserModel currentUser;
I have now put both parts of the code together and was able to display the string with the correct name. However, the Common.CurrentUser is not initialized what is not a problem as long as the Attributes are alright.
firebaseAuth = FirebaseAuth.getInstance();
firebaseDatabase = FirebaseDatabase.getInstance();
if(firebaseAuth.getCurrentUser()!=null) {
final FirebaseDatabase database =FirebaseDatabase.getInstance();
DatabaseReference myref=database.getReference("Users").child(firebaseAuth.getUid());
myref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
UserModel userModel= dataSnapshot.getValue(UserModel.class);
System.out.println(userModel.getName());
Common.setSpanString("Hey, ", userModel.getName(), txt_user);
currentUser=userModel;
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(HomeActivity.this, ""+databaseError.getCode(), Toast.LENGTH_SHORT).show();
}
});
}else{
UserModel userModel = new UserModel(uid,name,address,phone,email,password);
userModel.setName("Example Name");
Common.setSpanString("Hey, ", userModel.getName(), txt_user);
}
I'm following a retrofit course in which I create a small backend with an api in which I have a POST method to perform a teacher's login. In the course what he does is create a teacher and with the set method he passes him the email and the password, which is what this method receives in the API.
I would like to do it in such a way that in the call to Retrofit you pass directly this email and password and I have done it in the following way:
public class LoginActivity extends AppCompatActivity {
private EditText etPasswordLogin, etEmailLogin;
private Button btLogin;
private TextView tvSignUp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
setupView();
}
private void setupView() {
etPasswordLogin = findViewById(R.id.loginEditTextPassword);
etEmailLogin = findViewById(R.id.loginEditTextEmail);
btLogin = findViewById(R.id.buttonSignUp);
tvSignUp = findViewById(R.id.textViewSignUp);
btLogin.setOnClickListener(v -> userSignUp());
tvSignUp.setOnClickListener(v -> startActivity(new Intent(getApplicationContext(), SignUpActivity.class)));
}
private void userSignUp() {
String email = etEmailLogin.getText().toString().trim();
String password = etPasswordLogin.getText().toString().trim();
if (email.isEmpty()) {
etEmailLogin.setError(getResources().getString(R.string.email_error));
etEmailLogin.requestFocus();
return;
}
if (!Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
etEmailLogin.setError(getResources().getString(R.string.email_doesnt_match));
etEmailLogin.requestFocus();
return;
}
if (password.isEmpty()) {
etPasswordLogin.setError(getResources().getString(R.string.password_error));
etPasswordLogin.requestFocus();
return;
}
if (password.length() < 4) {
etPasswordLogin.setError(getResources().getString(R.string.password_error_less_than));
etPasswordLogin.requestFocus();
return;
}
login(email, password);
}
private void login(String email, String password) {
String BASE_URL = "http://10.0.2.2:8040";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
WebServiceApi api = retrofit.create(WebServiceApi.class);
Call<List<Profesor>> call = api.login(email, password);
call.enqueue(new Callback<List<Profesor>>() {
#Override
public void onResponse(Call<List<Profesor>> call, Response<List<Profesor>> response) {
if (response.code() == 200) {
Log.d("TAG1", "Profesor logeado");
} else if (response.code() == 404) {
Log.d("TAG1", "Profesor no existe");
} else {
Log.d("TAG1", "Error desconocido");
}
}
#Override
public void onFailure(Call<List<Profesor>> call, Throwable t) {
Log.d("TAG Error: ", Objects.requireNonNull(t.getMessage()));
}
});
}
}
And this would be my model teacher:
public class Profesor {
#SerializedName("id")
private Long id;
#SerializedName("nombre")
private String nombre;
#SerializedName("email")
private String email;
#SerializedName("password")
private String password;
#SerializedName("foto")
private String photo;
public Profesor(){}
public Profesor(Long id, String nombre, String email, String photo) {
this.id = id;
this.nombre = nombre;
this.email = email;
this.photo = photo;
}
public Profesor(String email, String password){
this.email = email;
this.password = password;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPhoto() {
return photo;
}
public void setPhoto(String photo) {
this.photo = photo;
}
}
Finally the call to Retrofit that I make is the following:
#FormUrlEncoded
#POST("api/login")
Call<List<Profesor>> login(#Field("email") String email, #Field("password") String password);
However when I run the application and pass through the form the email and password, in the log I return "Error desconocido", however in postman gives me answer without problems:
Any idea what I'm doing wrong?
Your postman request is not a form-urlencoded, but raw.
You need to send a json as a request, and not a field. So to fix this, you may change your API, to handle form-urlencoded requests, or change the Android code this way.
public class LoginCredentials {
#SerializedName("email")
private String email;
#SerializedName("password")
private String password;
public LoginCredentials(String email, String password) {
this.email = email;
this.password = password;
}
}
and change this
#FormUrlEncoded
#POST("api/login")
Call<List<Profesor>> login(#Field("email") String email, #Field("password") String password);
to this
#POST("api/login")
Call<List<Profesor>> login(#Body LoginCredentials credentials);
Hope this will help.
I have looked everywhere on stackoverflow and can't find my issue what i am trying to retrive is a users id from the database to show all users that are online except that user, however all the database info is being stored except the id resulting in the following crash
E/UncaughtException: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
at USER.UsersFragment$1.onDataChange(UsersFragment.java:63).
Here is my users file
public class User {
private String id;
private String username;
private String first_name;
private String last_name;
private String birthday;
private String email;
private String imageURL;
public User(String id, String username, String first_name, String last_name, String birthday, String email, String imageURL) {
this.id = id;
this.username = username;
this.first_name = first_name;
this.last_name = last_name;
this.birthday = birthday;
this.email = email;
this.imageURL = imageURL;
}
public User() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getFirst_name() {
return first_name;
}
public void setFirst_name(String first_name) {
this.first_name = first_name;
}
public String getLast_name() {
return last_name;
}
public void setLast_name(String last_name) {
this.last_name = last_name;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getImageURL() {
return imageURL;
}
public void setImageURL(String imageURL) {
this.imageURL = imageURL;
}
}
Here is how I am storing my info into the variables, the line where it crashes is labeled CRASH.
final FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference("users");
dbRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
mUsernames.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
User user = snapshot.getValue(User.class);
assert user != null;
if(!user.getId().equals(firebaseUser.getUid())) { <-CRASH
mUsernames.add(user);
}
//Log.println(Log.DEBUG, "", user.getId());
}
userAdapter = new UserAdapter(getContext(), mUsernames);
recyclerView.setAdapter(userAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
The problem is that in your database, you have more than one record. But only one record contains the field id.
Therefore when retrieving the data it is retrieving from the node that does not contain the node id and return an error.
Your database records don't have a field called "id", which means that getId() is always going to return null. The data is simply not there.
It looks like you probably want to use the key of the snapshot from snapshot.getKey().
How can I add Name along with email and password to firebase database android?
I added an email and password with function createUserWithEmailAndPassword and call a function:
createNewUser(task.getResult().getUser());
when successfull and in createnewUser im doing this
private void createNewUser(FirebaseUser userFromRegistration) {
String username = nameEditText.getText().toString();
String email = userFromRegistration.getEmail();
String userId = userFromRegistration.getUid();
User user = new User();
user.setName(username);
user.setUid(userId);
user.setEmail(email);
Log.d("Raza",mDatabase.child("users").push().setValue(user).isSuccessful()+"");
}
But I'm getting False at Log.d and the username is not added to my database.
My User Class is this:
public class User {
String name;
String uid;
String email;
public User(){
// Default constructor required
}
public void setName(String name){this.name = name;}
public void setUid(String uid){this.uid = uid;}
public void setEmail(String email){this.email = email;}
public String getName(){return this.name;}
}
Please help me on this.
Model Class
public class User {
public String uid;
public String email;
public String user_name;
public User(){
}
public User(String uid, String email String user_name)
{
this.uid = uid;
this.email = email;
this.user_name=user_name;
}
}
and Push data into firebase data like that
DatabaseReference database = FirebaseDatabase.getInstance().getReference();
User user = new User(firebaseUser.getUid(),
firebaseUser.getEmail(),
MySharedPreferences.getString(Constants.KEY_USER_NAME));
database.child(Constants.ARG_USERS)
.child(firebaseUser.getUid())
.setValue(user)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
// mOnUserDatabaseListener.onSuccess(context.getString(R.string.user_successfully_added));
} else {
// mOnUserDatabaseListener.onFailure(context.getString(R.string.user_unable_to_add));
}
}
});
I want to create a function that iterates through a firebase structure looking like this:
{
"users":{
"7e122736-2dd4-4770-a360-a0e7cbe41a43":{
"currentLatitude":46.6598714,
"currentLongitude":23.5637339,
"displayName":"gjsj2",
"email":"2#vlad.com",
"password":"123"
},
"a09e7e1d-ad3a-4d21-b0ba-069e0999bb93":{
"currentLatitude":47.6599014,
"currentLongitude":23.5636797,
"displayName":"gjsj",
"email":"1#vlad.com",
"password":"123"
},
"abc29286-fd6d-4088-95da-759828b5835d":{
"currentLatitude":50.6599043,
"currentLongitude":23525.5637188,
"displayName":"gjsj3",
"email":"3#vlad.com",
"password":"123"
}
}
}
I want to create a function that takes every unique user id's child and uses his coordinates to create a marker on a google maps map. Here's what i got so far but it doesnt seem to be working :
public void onChildChanged(DataSnapshot snapshot, String s) {
for (DataSnapshot userSnapshot : snapshot.getChildren()) {
for (DataSnapshot uniqueUserSnapshot : userSnapshot.getChildren()) {
Users currentUser = uniqueUserSnapshot.getValue(Users.class);
MarkerOptions options = new MarkerOptions()
.title(currentUser.getEmail())
.icon(BitmapDescriptorFactory.defaultMarker(getRandomNumberInRange(0, 360)))
.position(new LatLng(currentUser.getCurrentLatitude(), currentUser.getCurrentLongitude()));
mMap.addMarker(options);
Toast.makeText(MainActivity.this, "fsafasfasfas", Toast.LENGTH_SHORT).show();
}
}
}
And here's my Users POJO:
package com.licenta.vladut.mmap;
public class Users {
String email;
String displayName;
String password;
double currentLatitude;
double currentLongitude;
public Users() {
}
public Users(String email, String displayName, String password, double currentLongitude, double currentLatitude) {
this.email = email;
this.displayName = displayName;
this.password = password;
this.currentLongitude = currentLongitude;
this.currentLatitude = currentLatitude;
}
public Users(String email, String displayName, String password) {
this.email = email;
this.displayName = displayName;
this.password = password;
}
public String getDisplayName() {
return displayName;
}
public String getEmail() {
return email;
}
public String getPassword() {
return password;
}
public double getCurrentLongitude() {
return currentLongitude;
}
public double getCurrentLatitude() {
return currentLatitude;
}
}
If I understand the question correctly, you are actually close to what you want to do. Reference the database child user, and then add a ValueEventListener:
Firebase userRef = new Firebase(/*url*/);
userRef = userRef.child("users");
userRef.addValueEventListener(new ValueEventListener(){
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot uniqueUserSnapshot : dataSnapshot.getChildren()) {
...
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
ValueEventListener returns the node called, not children one by one.