I'm learning how to write data to Firebase RealTime Database, but after some tests I can't put new data into my DB and I haven't had any error from the app.
Here is my code:
MainActivity.class
public class MainActivity extends AppCompatActivity {
EditText mName;
Button button;
DatabaseReference root;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mName = findViewById(R.id.etMess);
button = findViewById(R.id.btInvia);
root = FirebaseDatabase.getInstance().getReference().child("student");
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
insertData();
}
});
}
private void insertData() {
String name = mName.getText().toString();
Dati dati = new Dati(name);
root.push().setValue(dati);
Toast.makeText(this,"Data inserted",Toast.LENGTH_SHORT).show();
}
}
Dati.class
public class Dati {
String name;
public Dati(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Rules from my db are:
{
"rules": {
".read": true,
".write": true
}
}
I tried to read something from DB using get() function, but I had an error:
get for query / falling back to disk cache after error: Client is offline java.lang.Exception: Client is offline
Any help appreciated.
Related
I am trying to save a message object in the firebase database, when I run the code I get no errors, everything looks to be fine but when I go to firebase website, nothing appears in the database
public class MainChatActivity extends AppCompatActivity {
private DatabaseReference mDatabaseReference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_chat);
mDatabaseReference = FirebaseDatabase.getInstance().getReference();
mSendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sendMessage();
}
});
}
private void sendMessage() {
String input = mInputText.getText().toString();
if(!input.equals("")){
InstantMessage chat=new InstantMessage(input, mDisplayName);
mDatabaseReference.child("children").push().setValue(chat);
mInputText.setText("");
}
}
}
public class InstantMessage {
private String message;
private String author;
public InstantMessage(String message, String author) {
this.message = message;
this.author = author;
}
public InstantMessage() {
}
public String getMessage() {
return message;
}
public String getAuthor() {
return author;
}
}
I expect to save the message with author name in a directory named "messages" in firebase, but that's not happening
Change your firebase database rules to the following:
{
"rules": {
".read": true
".write": true
}
}
It allows read/write access to all users under any conditions.
Warning: NEVER use this ruleset in production; it allows anyone to overwrite your entire database.
try this:
public class MainChatActivity extends AppCompatActivity {
private DatabaseReference mDatabaseReference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_chat);
mDatabaseReference = FirebaseDatabase.getInstance().getReference();
mSendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sendMessage();
}
});
}
private void sendMessage() {
String input = mInputText.getText().toString();
if(!input.equals("")){
InstantMessage chat=new InstantMessage(input, mDisplayName);
String key = mDatabaseReference.push().getKey();
mDatabaseReference.child("messages").child(key).setValue(chat) //here you can add a Listener to check success;
mInputText.setText("");
}
}
}
public class InstantMessage {
private String message;
private String author;
public InstantMessage(String message, String author) {
this.message = message;
this.author = author;
}
public InstantMessage() {
}
public String getMessage() {
return message;
}
public String getAuthor() {
return author;
}
}
It seems its permission issue
Make sure you are permission for READ/WRITE on the database, check the rules and make them public
{
"rules": {
".read": true
".write": true
}
}
I am new to app development (android studio).
I have two classes one is main and the other class (database) which connects to firebase and checks if the user exists or not and replies true or false respectively and also prints out some statements.
The problem is the android studio does not wait for a response even if the task is successful and replies a false.
print statement I should be getting in the logcat should be
"here 1", "here 2", and then "here 3". but it gives me "here 2", "here 3" and then "here 1".
I know it has to do something with threading or something like that.
public class loginpage extends AppCompatActivity {
private Button Login;
private EditText user_email_txt;
private EditText user_password_txt;
private ProgressBar wait_bar;
private String[] user_name_password ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
find_all_views();
Login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getuser_login_details();
disable_all_views();
Activate_wait_bar();
final Database login = new Database();
boolean decision = login.sign_in(user_name_password[0], user_name_password[1]);
System.out.println("here 3");
}
});
}
private void find_all_views() {
user_email_txt = findViewById(R.id.UserName);
user_password_txt = findViewById(R.id.Password);
Login = findViewById(R.id.submit_button);
wait_bar = findViewById(R.id.wait_bar);
}
private void getuser_login_details() {
user_name_password = new String[2];
user_name_password[0] = user_email_txt.getText().toString();
user_name_password[1] = user_password_txt.getText().toString();
}
private void disable_all_views() {
user_email_txt.setVisibility(View.INVISIBLE);
user_password_txt.setVisibility(View.INVISIBLE);
Login.setVisibility(View.INVISIBLE);
}
private void Activate_wait_bar() {
wait_bar.setVisibility(View.VISIBLE);
}
}
public class Database {
private FirebaseAuth connect_databse;
private boolean authorisation;
public Database() {}
public boolean sign_in(String user_name, String Password) {
authorisation = false;
connect_databse = FirebaseAuth.getInstance();
connect_databse.signInWithEmailAndPassword(user_name, Password)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
FirebaseUser user = connect_databse.getCurrentUser();
authorisation = true;
System.out.println("here 1");
}
}
});
System.out.println("here 2");
return authorisation;
}
}
if the task is successful it should return authorization = true with print statements "here 1", "here 2", and then "here 3" in order.
create a new file:
interface OnCompleteListener {
void onComplete();
}
In Database class:
public class Database {
private FirebaseAuth connect_databse;
private boolean authorisation;
public Database() {
}
public void sign_in(String user_name, String Password,final OnCompleteListener listener) {
authorisation = false;
connect_databse = FirebaseAuth.getInstance();
connect_databse.signInWithEmailAndPassword(user_name, Password)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
FirebaseUser user = connect_databse.getCurrentUser();
authorisation = true;
System.out.println("here 1");
listener.onComplete();
System.out.println("here 2");
}
}
});
}
In Activity:
Login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getuser_login_details();
disable_all_views();
Activate_wait_bar();
final Database login = new Database();
boolean decision = login.sign_in(user_name_password[0], user_name_password[1], new OnCompleteListener{
#Override
public void onComplete(){
System.out.println("here 3");
}
});
}
});
When you work with Network Connection or Call an API to get data from a server, you must use Background Thread and after the task completed, your code in OnComplete run. but main Thread doesn't stop for your task and run all code out of OnComplete method sequentially.
In this situation, you can use CallBackMethod.
I'm testing Firebase by building an app that simply puts a message in the Database (authorisations are set to true for the test), it worked only once, and now nothing is pushed to the database. But as you can see I put logs everywhere to see where the problem is and surprisingly the onChildEventListener() seems to notice a change.
Here is the code for my main activity :
public class MainActivity extends AppCompatActivity {
public final static String TAG = "Main Activity";
public final int[] id = {0};
Button sendButton;
EditText messageEditText;
String message;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
id[0] = 0;
sendButton = findViewById(R.id.send_message);
messageEditText = findViewById(R.id.message_text);
final DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("test/geomessage/");
sendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
message = messageEditText.getText().toString();
Log.e(TAG, "Test 1");
GeoMessage currentGeomessage = new GeoMessage(id[0], message);
Log.e(TAG, "Test 2");
databaseReference.child("children").push().setValue(currentGeomessage).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.e(TAG, "Success !");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e(TAG, "FAIL");
}
}).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Log.e(TAG, "Complete");
}
});
Log.e(TAG, "Test 3");
}
});
databaseReference.child("children").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Log.e("101", "Child Added !");
id[0] = (int) dataSnapshot.getChildrenCount();
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
Log.e("101", "Child CHanged !");
id[0] = (int) dataSnapshot.getChildrenCount();
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private static class GeoMessage {
int id;
String content;
public GeoMessage() {};
public GeoMessage(int id, String content) {
this.id = id;
this.content = content;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
}
Here are the logs when I click on the "Send" Button :
11-03 19:02:13.338 7440-7440/com.example.brumor.geofiretest E/Main Activity: Test 1
11-03 19:02:13.338 7440-7440/com.example.brumor.geofiretest E/Main Activity: Test 2
11-03 19:02:13.340 7440-7440/com.example.brumor.geofiretest E/Main Activity: Test 3
11-03 19:02:13.420 7440-7440/com.example.brumor.geofiretest E/101: Child Added !
The observed behavior occurs when the device does not have a connection to the Firebase servers. Calls to setValue() change the DB cache held locally in the client. This causes listeners for the changed location to fire. But the completion listeners for setValue() do not fire until the update to the Firebase server completes successfully or fails.
Check that your device has a network connection. You can detect the Firebase connection status using the example here.
sendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
message = messageEditText.getText().toString();
GeoMessage currentGeomessage = new GeoMessage(id[0], message);
databaseReference.child("children").push().setValue(currentGeomessage);
}
});
No need to use addonSuccessListener to store data. Also it is not even entering the method addonSuccessListener , so its skipping the whole method and then it prints the Log for you, but nothing is entering the database. Usually onSuccessListener is used for firebase storage, to see if the task is successful or not.
Also according to this page: https://firebase.google.com/docs/reference/admin/java/reference/com/google/firebase/tasks/Task
public abstract Task<T> addOnSuccessListener (OnSuccessListener<? super T> listener)
The above method is deprecated.
You have to use this now:
public abstract Task<T> addOnSuccessListener (Executor executor, OnSuccessListener<? super T> listener)
These two methods addUser() and viewDetails() methods are not being used in this my main activity file. I could find the reason, I don't know where do I have to call them. I am using Android Studio.
public class MainActivity extends AppCompatActivity {
EditText userName, password;
DatabaseAdapter databaseHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
userName = (EditText) findViewById(R.id.editTextUser);
password = (EditText) findViewById(R.id.editTextPass);
databaseHelper = new DatabaseAdapter(this);
}
public void addUser(View view) {
String user = userName.getText().toString();
String pass = password.getText().toString();
long id = databaseHelper.insertData(user, pass);
if (id < 0) {
Message.message(this, "Unsuccessful");
} else {
Message.message(this, "Successful");
}
}
public void viewDetails(View view) {
String data = databaseHelper.getAllData();
Message.message(this, data);
}
}
After watching this code you are only declaring a function and give the definition of the function you are not using it or calling it .. any where that's why android studio show you not using this method's...
You can call this method like addUser(); or viewDetails();
I am using Firebase, and I am trying to show data from Firebase through my Android app. Yet, when I run the app, it crashes and logcat says "failed to bounce to type". I mimicked the properties of the JSON structure in a java class.
Here is the MainActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Firebase.setAndroidContext(this);
Firebase ref = new Firebase("https://fbandg.firebaseio.com/");
android.R.layout.simple_list_item_1, android.R.id.text1);
final TextView textbox = (TextView) findViewById(R.id.textbox);
Firebase.setAndroidContext(this);
ValueEventListener newCon = ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
fObject obj = dataSnapshot.getValue(fObject.class); //Line 49
textbox.setText(obj.toString());
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
Here is the Java class I created:
public class fObject
{
String newCond;
public String getCondition()
{
return newCond;
}
}
The errors produced are the following:
firebase.client.DataSnapshot.getValue(DataSnapshot.java:183)
com.example.elish_000.myfirstapp.MainActivity$1.onDataChange(MainActivity.java:49)
Try this,
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Firebase.setAndroidContext(this);
Firebase ref = new Firebase("https://fbandg.firebaseio.com");
final TextView textbox = (TextView) findViewById(R.id.textbox);
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
fObject fobject = new fObject();
fobject.setNewCondition(dataSnapshot.child("condition").getValue().toString());
textbox.setText(fobject.getNewCondition());
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
modify your fObject class,
public class fObject
{
String newCond;
public String getNewCond()
{
return newCond;
}
public void setNewCond(String cond)
{
newCond = cond;
}
}
Firebase's JSON-to-Java mapper uses a JavaBean pattern to determine how to map fields. For a class to be a valid JavaBean, the field name and the getter/setter need to match.
To make your class work, change it to:
public class fObject
{
String newCond;
public String getNewCond()
{
return newCond;
}
}
You can then read it from a DataSnapshot with:
fObject obj = dataSnapshot.getValue(fObject.class);
I've covered this extensively a while ago: Why do I get "Failed to bounce to type" when I turn JSON from Firebase into Java objects?. You should probably read that too.