Firebase Database Query Not Working - android

I am trying to create a Firebase Login and Register App. I have setup that At the time of registration android id will save to the database. If the Android Id exits with another account the user can't create account . when i run the app and try to register an account its shows "Registering Please Wait..." and nothings happens . How can i fix this?

To solve this problem and all your problems regarding authentication is suggest you using Firebase Authentication.
It's very easy to implement and you'll don't have in the future any code to maintain.
To find serial number of Android device please use this code:
TelephonyManager tManager = (TelephonyManager)myActivity.getSystemService(Context.TELEPHONY_SERVICE);
String androidSerialNumber = tManager.getDeviceId();
Having this androidSerialNumber you can use it to save it in your database.
0down voteaccepted
Another approach will be to change The Rule Of Database like this:
{ "rules":
{ ".read": "true",
".write": "auth != null"
}
}

Change the code to this .
if(task.isSuccessful()){
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
rootRef.child(firebaseAuth.getCurrentUser().getUid()).child("Id").setValue(android_id);
progressDialog.dismiss();
startActivity(new Intent(getApplicationContext(), ProfileActivity.class));
finish();
}
and also dismiss the progressDialog when the query is canceled
#Override
public void onCancelled(DatabaseError databaseError) {
progressDialog.dismiss();
}
});

Related

Firebase Realtime Database xxxx-xxxx-4458' has insecure rules - Followup Question

I previously asked question to secure realtime database on firebase. I am only using Firebase Realtime database just to creating chat app. The user verification working separately on our own server and we are not using any firebase auth service for user verification. As Frank van Puffelen suggested few official docs. I am now generating JWT to authorize as per documentation but as we are not using any other services of firebase i am not sure how to authorized the real time database with generated JWT.
mAuth.signInWithCustomToken(mCustomToken)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// Sign in success
} else {
// If sign in fails
Toast.makeText(CustomAuthActivity.this, "Authentication failed.",
}
}
});
How to validate users and secure our database from world so only app user can edit their node only.
I followed this guide for
Authenticate with Firebase with custom token.
User login with their credential
Server generate custom token (JWT).
Pass it to signInWithCustomToken as per doc.
What after that? guide bit incomplete for my use case.
Edit: The process:
Server generates JWT With PHP Firebase JWT
$Token = JWT::encode($request_data,$secret_Key,'HS512');
this token return back to app if user login successfully.
After successfully user login i call sign in with custom token i received from server with firebase
firebaseAuth = FirebaseAuth.getInstance();
firebaseAuth.signInWithCustomToken(Session.getJWT())
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isComplete()){
Intent intent=new Intent(getActivity(),MainActivity.class);
getActivity().startActivity(intent);
}
}
});
When user click chat button. Check if room already exist or not if not then create one for 2 users with their phone numbers like 9810012345-9810012346
DatabaseReference db = rebaseDatabase.getInstance().getReference();
db.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.hasChild(RoomTitle)) {
RoomName(RoomTitle, true);
}else {
RoomName(RoomTitle, false);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
public void RoomName(String Name, boolean RoomExist) {
button_SendMessage.setEnabled(true);
if (!RoomExist) {
Log.d(TAG, "Room Not Exist Creating One);
RoomName.put(Name, "");
FireBaseDatabase.updateChildren(RoomName);
}
// Launch Chat Screen
}
Then on chat screen i add items like linked question database structure
databaseReference = FirebaseDatabase.getInstance().getReference().child(Room_Name);
So creating room,allow reading writing message only created room, block access if room doesn't belong to users. I need to set rules for Realtime Database and only app users can access their rooms not others even they are app users(Block others app users to sneak into others users rooms) Below is the sample of our Realtime Database structure for better understanding how our 2 user room look like. I am not sure there is much thing to do on app side, i feel it's more database than app code question.
Once your call to signInWithCustomToken succeeds, that token will be passed to the server whenever the Firebase Realtime Database SDK connects, and from there on it will be verified and passed on to the auth variable in your security rules.
So you can check if the request comes from a signed-in user with:
{
"rules": {
".read": "auth.uid !== null",
".write": "auth.uid !== null"
}
}
That's a bit broad though, so you'll want to narrow it down to specific users. For example, you can allow only a content-owner access with:
{
"rules": {
"some_path": {
"$uid": {
// Allow only authenticated content owners access to their data
".read": "auth !== null && auth.uid === $uid",
".write": "auth !== null && auth.uid === $uid"
}
}
}
}
Any claims you have in your JWT will be available in the security rules too under the auth.token variable.

how to know if a valid FirebaseAuth is going to expire soon

I've a weird behavior in my app related to the firebase database.
I got some unexpected access denied when trying to perform some stuff at database... That could be bug in my code but is a pretty simple code.
I want to ilustrate the sitation with a real scenario, please read the requirements
1- i've only 1 app accessing the database (android)
2- i've only 1 method in the whole app trying to access the specific node which is causing deny of access
3- in my firebase rules the only rule applied to this node is:
".read":"auth != null",
".write":"auth != null"
4- i DO explicity check FirebaseAuth.getInstance().getCurrentUser() != null right before calling the method
this is a pseudo snippet of how my code is (i wont pust the real code simple because is too long)
public void onResume() {
if(FirebaseAuth.getInstance().getCurrentUser() == null)
doLogin();
else
checkFirebaseStuff();
}
As google doesn't provide any info about why the access was rejected the only possible explanation i found is:
the user was authenticated but long time before, so when it checked on if was still valid, but short time later when the function really ran its token (or some other firebase auth check) was no longer valid, so it caused the access denied
this error doesn't happen a lot, i have 5k daily users and it happens around 20 or 50 times a day, but still shouldn't happen even once
does it make sense? can anyone help me with any aditional info?
Hmm, I think you can fix this by checking if the user is disconnected from the firebase database, but I'm not really sure if that will affect the Auth too, you can give it a try
DatabaseReference connectedRef = FirebaseDatabase.getInstance().getReference(".info/connected");
connectedRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
boolean connected = snapshot.getValue(Boolean.class);
if (connected) {
Log.d(TAG, "connected");
//Here you can update your mAuth state
} else {
Log.d(TAG, "not connected");
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Log.w(TAG, "Listener was cancelled");
}
});

Creating anonymous user in Firebase doesn't work

I have been trying to solve this problem for more than 4 hours now, still nothing...
I want that only signed in users can write and read data to my database, so I decided to create anonymous user. I set firebase rules like this:
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
Now I have this code in my MainActivity:
mAuth = FirebaseAuth.getInstance();
mAuth.signInAnonymously().addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
System.out.print("NEW USER SIGNED IN?");
} else {
Log.d(TAG, "Fail");
}
}
});
The purpose of this code is to create an anonymous user, which can read and write into my database, but this code isn't even getting invoked.
Is this the correct way to create an anonymous user which may read and write data into my firebase database?
If you have followed these steps:
https://firebase.google.com/docs/auth/android/anonymous-auth
Added Firebase to your project, added the dependency and enabled the anonymous auth (which you do in the firebase auth console), this code should work.
If you use an emulator, make sure it has internet connection.

Firebase create user without sign in [duplicate]

This question already has answers here:
Firebase kicks out current user
(19 answers)
Closed 6 years ago.
I wish to create a new user account from my application when logged in as a "admin user", The issue is i just want to create it not actually sign in.
is it possible to disable the automatic sign in when creating a new user with the email / password.
I see others have asked this question in relation to JS and swift but can not seem to find any android specific related info. i'm trying to achieve the same thing as this person but with android
any help appreciated
Here is a tested solution you can apply (just implemented a few minutes before).
For creating a new user account you need the reference of FirebaseAuth.
So you can create two different FirebaseAuth objects like:
private FirebaseAuth mAuth1;
private FirebaseAuth mAuth2;
Now in the onCreate you can initialize them as:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
mAuth1 = FirebaseAuth.getInstance();
FirebaseOptions firebaseOptions = new FirebaseOptions.Builder()
.setDatabaseUrl("[Database_url_here]")
.setApiKey("Web_API_KEY_HERE")
.setApplicationId("PROJECT_ID_HERE").build();
try { FirebaseApp myApp = FirebaseApp.initializeApp(getApplicationContext(), firebaseOptions, "AnyAppName");
mAuth2 = FirebaseAuth.getInstance(myApp);
} catch (IllegalStateException e){
mAuth2 = FirebaseAuth.getInstance(FirebaseApp.getInstance("AnyAppName"));
}
//..... other code here
}
To get ProjectID, WebAPI key you can go to Project Settings in your firebase project console.
Now to create the user account you have to use mAuth2, not mAuth1. And then on successful registration, you can log out that mAuth2 user.
Example:
private void createAccount(String email, String password)
{
mAuth2.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (!task.isSuccessful()) {
String ex = task.getException().toString();
Toast.makeText(RegisterActivity.this, "Registration Failed"+ex,
Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(RegisterActivity.this, "Registration successful",
Toast.LENGTH_SHORT).show();
mAuth2.signOut();
}
// ...
}
});
}
The point where you have to worry(actually not):
The admin should only be able to create the new user accounts. But the above solutions is allowing all authenticated user to create a new user account.
So to solve this problem you can take help of your firebase real-time database. Just add a key like "is_user_admin" and set the value as true from the console itself. You just need to validate the user before someone is trying to create a new user account. And using this approach you can set your own admin.
As of now, I don't think there is firebase-admin SDK for android. So one can use the above approach.

Add extra User Information with firebase

I have integrated firebase auth with my android app. Lets say a user has a mail abc#abc.com. I want to add some extra information to the user like the name of the user, occupation and address. How can i connect the user auth table with my android app to do that?
Do i need to write any APIs for that?
First, create a users directory in db. Then, using user's unique id you get from authn process, store the user info under users/{userid}.
To achieve this, you need to get into the details of Firebase database. See here: https://firebase.google.com/docs/database/android/save-data
You do not need to write any custom code to do this. Firebase already has features you can use.
The first thing you'd need to do is ensure that users have access to only the data they store. To do this, go to Database/Rules and change your rules to this:
{
"rules": {
"my_app_user": {
"$uid": {
".write": "auth != null && auth.uid == $uid",
".read": "auth != null && auth.uid == $uid"
}
}
}
}
Then, to save the new details in a Firebase database, do this:
MyAppUser user = new MyAppUser();
user.setAddressTwo("address_two");
user.setPhoneOne("phone_one");
...
mDatabaseReference.child("my_app_user").child(firebaseUser.getUid()).setValue(user).
addOnCompleteListener(DetailsCaptureActivity.this,
new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
...
The name of the child my_app_user must match both in your code and the Firebase rules else it won't persist.
If everything goes as is supposed to, you should see the details in your database:
You have to create another database table say "user". On successful signin, signup for first time you have to create a new row in user table.
public static void writeNewUser(DatabaseReference databaseReference, String userId, String name, String email, int accountType) {
User user = new User(name, email, accountType);
databaseReference.child("users").child(userId).setValue(user);
}
You may refer https://github.com/firebase/quickstart-android/tree/61f8eb53020e38b1fdc5aaeddac2379b25240f3b/database

Categories

Resources