Hy Developers, I am new to android development so that's why facing an issue in saving and viewing data to my android app.
I know that data can only be retrieved while you are connected to internet.
But the thing is it is retrieving data and also showing to android log.
But when i try to save it to a string variable or to arraylist to show
it on main activity using that list or variable, its not working.
I am declaring a private string variable to store value from firebase database before onCreate method.
Sorry for my nob question. But this is the issue i am facing.
Following is the code that i am using and some screenshots to make the question understandable.
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Firelog" ;
Button ans1, ans2, ans3, ans4;
TextView uscore, question, timer;
private String mAnswer;
private ArrayList<String> fbquestions = new ArrayList<String>();
private String quest;
private int mScore = 0;
Random r = new Random();
private int res = 0;
private int c = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
uscore = (TextView) findViewById(R.id.uscore);
question = (TextView) findViewById(R.id.question);
timer = (TextView) findViewById(R.id.timer);
ans1 = (Button) findViewById(R.id.ans1);
ans2 = (Button) findViewById(R.id.ans2);
ans3 = (Button) findViewById(R.id.ans3);
ans4 = (Button) findViewById(R.id.ans4);
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("mcqs");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
Map <String, String> map = (Map)dataSnapshot.getValue();
quest = map.get("question");
fbquestions.add(quest);
Log.v("E_Value","Question is" + quest);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
question.setText(String.valueOf(fbquestions.get(0)));
}
}
In above pic you can see that question is retrieved successfully from firebase and visible in log.
But here when i try to display question on main screen after assigning, its showing blank.
After adding the code to add value to arraylist, application crashes..
You cannot simply get the value of fbquestions.get(0) outside the onDataChange() method because this method has an asynchronous behavior. So you cannot simply create your fbquestions list as a global variable and use it's value outside the callbakc because it will always be empty. Basically, you're trying to use a value synchronously from an API that's asynchronous. That's not a good idea. You should handle the APIs asynchronously as intended.
A quick solve for this problem would be to move the following line of code:
question.setText(String.valueOf(fbquestions.get(0)));
Inside the callback right after this line of code:
Log.v("E_Value","Question is" + quest);
And your problem will be solved. If you want to use the list outside, I recommend you see the last part of my anwser from this post in which I have explained how it can be done using a custom callback. You can also take a look at this video for a better understanding.
Pass quest value to Textview..
ArrayList<String> questionArrrayList =new Arraylist<>();
questionArrrayList .clear();
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
Map <String, String> map = (Map)dataSnapshot.getValue();
quest = map.get("question");
question.setText(quest);
questionArrrayList .add(quest);
Log.v("E_Value","Question is" + quest);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Related
I'm making a shopping app and User has to subscribe to the 'Fast-delivery' option if he needs to order it faster. When the User puts a tick to the 'Fast-delivery' Checkbox, the boolean value is being uploaded to the Firebase realtime database -->
database
And I want to see if the User has subscribed to the 'Fast-delivery' option from the Admin Panel. I retrieve all the order information to a RecyclerView in the Admin Panel. I want to set a TextView as "Fast Delivery : On/Off" when the Admin views the order details from the Admin Panel.
This is what I have tried:
#Override
protected void onStart()
{
super.onStart();
ordersRef = FirebaseDatabase.getInstance().getReference().child("Orders");
FirebaseRecyclerOptions<AdminOrders> options =
new FirebaseRecyclerOptions.Builder<AdminOrders>()
.setQuery(ordersRef, AdminOrders.class)
.build();
FirebaseRecyclerAdapter<AdminOrders, AdminOrdersViewHolder> adapter =
new FirebaseRecyclerAdapter<AdminOrders, AdminOrdersViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull final AdminOrdersViewHolder holder, final int position, final #NonNull AdminOrders model)
{
holder.userName.setText("Name: "+ model.getName());
holder.userPhoneNumber.setText("Phone Number: : "+ model.getPhone());
holder.userTotalPrice.setText("Total Amount: $"+ model.getTotalAmount());
holder.userDateTime.setText("Order Time: "+ model.getDate() + model.getTime());
holder.userShippingAddress.setText("Shipping Address: "+ model.getAddress() + "," + model.getCity());
holder.showOrdersBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
String uID = getRef(position).getKey();
Intent intent = new Intent(AdminNewOrdersActivity.this, AdminUserProductsActivity.class);
intent.putExtra("uid", uID);
startActivity(intent);
}
});
ordersRef.child(userID).child("fast_delivery").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
TextView switch1 = (TextView) findViewById(R.id.switch1);
switch1.setText(String.valueOf(this));
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
And I'm getting this error
java.lang.NullPointerException: Can't pass null for argument 'pathString' in child()
You have a NullPointerException indicating that userID is not initialized, hence this error:
Can't pass null for argument 'pathString' in child()
To solve this, please add the following line of code:
String userID = FirebaseAuth.getInstance().getCurrentUser().getUid();
Right in front of:
ordersRef.child(userID).child("fast_delivery").addValueEventListener(/* ... */);
i guess if im right.. you have created separate tree for orders where you are getting orders
create model class give name as same as childname are where you're getting boolean value of fast_delivery use that boolean value to convert it to string and hence compare that value if String.valueof(boolean)is="true" then print to textview or vise versa with off
I'm setting up an android apps that could show the personal data in two different activity. The data is stored in my firebase database, can anyone help me doing that?
I already tried to use addValueEventListener in both of my java classes. User's class that is responsible to display user information in User Profile activity is successfully retrieved the data from my firebase, but the other one still couldn't retrieve the data from my firebase.
This is the code from java class that couldn't retrieve the data from my firebase.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_land_profile);
mAuth = FirebaseAuth.getInstance();
mUser = mAuth.getCurrentUser();
mDBase = FirebaseDatabase.getInstance();
nama_lahan = (TextView) findViewById(R.id.nama_lahan);
lebar_lahan = (TextView) findViewById(R.id.lebar_lahan);
panjang_lahan = (TextView) findViewById(R.id.panjang_lahan);
luas_lahan = (TextView) findViewById(R.id.luas_lahan);
jenis_lahan = (TextView) findViewById(R.id.jenis_lahan);
jenis_pupuk = (TextView) findViewById(R.id.jenis_pupuk);
public void fetchLandData (String userUID){
mAkun = mDBase.getReference("Akun").child(userUID);
mAkun.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot landData : dataSnapshot.getChildren()){
Lahan lahan = landData.getValue(Lahan.class);
if(lahan != null){
namaLahan = lahan.getNamaLahan();
jns_lahan = lahan.getJenisLahan();
jns_pupuk = lahan.getJenisPupuk();
lebarLahan = lahan.getLebarLahan();
panjangLahan = lahan.getPanjangLahan();
luasLahan = panjangLahan*lebarLahan;
nama_lahan.setText(namaLahan);
jenis_pupuk.setText(jns_pupuk);
jenis_lahan.setText(jns_lahan);
lebar_lahan.setText(String.valueOf(lebarLahan));
panjang_lahan.setText(String.valueOf(panjangLahan));
luas_lahan.setText(String.valueOf(luasLahan));
}else{
Toast.makeText(LandProfileActivity.this, "Gak iso pisan ``bos", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
While the other one is pretty much the same structure but different variable name and it could give me the result that i wanted.
That is the screenshot from my application that failed to retrieve data from my firebase and
This is what my Firebase DB looks like
These are some error that i copied from my logcat :
2019-02-09 23:32:11.070 1645-3271/? E/ActivityTrigger: activityStartTrigger: not whiteListedcom.example.johno.test/com.example.johno.test.LandProfileActivity/1
2019-02-09 23:32:11.072 1645-3271/? E/ActivityTrigger: activityResumeTrigger: not whiteListedcom.example.johno.test/com.example.johno.test.LandProfileActivity/1
2019-02-09 23:32:11.079 1645-3065/? E/ActivityTrigger: activityResumeTrigger: not whiteListedcom.example.johno.test/com.example.johno.test.LandProfileActivity/1
you can put Firebase ValueEvent listener in Application class:
public class MyApplication extends Application {
//mAkun field declaration;
private ValueEventListener value_event_listener;
#Override
public void onCreate() {
mAkun = mDBase.getReference("Akun").child(userUID);
mAkun.addValueEventListener(new ValueEventListener() {/*..*/}
}
#Override
public void onTerminate() {
super.onTerminate();
mAkun.removeEventListener(value_event_listener);
}
}
I am using an ArrayList (in Android) that contains the values from the Firebase database. Whenever the data is added or deleted, I want the list to be updated. To do this I used ChildEventListener but I am unsure whether this is a proper way of doing it as I face errors sometimes while deleting the elements from the list. There's no problem at all when adding elements to the list. But When I try to delete the last element from the list, I get ArrayIndexOutOfBounds Exception or some other Exception like length=12 index=-1. So, please go through my code and suggest a better way to delete elements:
public class Join extends AppCompatActivity {
DatabaseReference databaseReference;
ListView listView;
public static ArrayList<String> keysArrayList;
//To store the keys from Firebase
public static ArrayList<String> namesArrayList;
//To store the value or name associated with the key
ArrayAdapter<String> arrayAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_join);
databaseReference = FirebaseDatabase.getInstance().getReference().child(“Queue Codes”);
listView = (ListView) findViewById(R.id.listViewForMember);
keysArrayList = new ArrayList<>();
namesArrayList = new ArrayList<>();
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>
(this,android.R.layout.activity_list_item,namesArrayList);
listView.setAdapter(arrayAdapter);
/* Here I am trying to store Random keys from Firebase in
‘keysArrayList’ and their values in ‘namesArrayList’ and update these
lists whenever a value is added or removed from the database*/
databaseReference.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
String addedKey = dataSnapshot.getKey();
String addedName = dataSnapshot.getValue(String.class);
keysArrayList.add(addedKey);
namesArrayList.add(addedName);
arrayAdapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
String removedKey = dataSnapshot.getKey();
int index = keysArrayList.indexOf(removedKey);
namesArrayList.remove(index);
keysArrayList.remove(removedKey);
arrayAdapter.notifyDataSetChanged();
/* Here I tried to remove the name from the ‘namesArrayList’ by
using the index of removed value from ‘keysArrayList’ as both
the lists would be of the same size anytime. I can simply
delete the name from the ‘namesArrayList’ by reading the
removed value from firebase but gets difficult when I use
Custom Array Lists which may contain many other objects. So, I
decided to delete the name using key index. */
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
In order to solve this problem, you need to remove that particular element first from the adapter. If you want not to worry about adding or removing elements, I recommend you see my answer from this post, in which I have explained how you can get data from the Firebase Realtime database and display it in a ListView using an ArrayAdapter.
Iam beginner with the firebase, and iam trying to insert data into the firebase, I faced a problem, that when I pressed insert button, the same data is submitted many times and it doesnt stop inserting until the run is stopped
I am using push() function but i dont know where the problem is in my code
can any one help me?
my firebase looks like this when i submitted one data
here is my code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fill_request_page);
Title = (EditText) findViewById(R.id.Title);
Content = (EditText) findViewById(R.id.Content);
insert =(Button) findViewById(R.id.insert);
edittxtDate =(EditText) findViewById(R.id.edittxtDate);
edittxtTime =(EditText) findViewById(R.id.edittxtTime);
edittxtExpDate=(EditText) findViewById(R.id.edittxtExpDate);
location = (Spinner) findViewById(R.id.location);
typeof=(Spinner)findViewById(R.id.typeof);
database = FirebaseDatabase.getInstance();
ref1 = database.getReference("requests");
imagebtnTime.setOnClickListener(this);
storage = FirebaseStorage.getInstance();
storageReference = storage.getReference();
private void getValues(){
request1.setTitle(Title.getText().toString());
request1.setContent(Content.getText().toString());
request1.setDate(edittxtDate.getText().toString());
request1.setTime(edittxtTime.getText().toString());
request1.setLocation(location.getSelectedItem().toString());
request1.setExpDate(edittxtExpDate.getText().toString());
request1.setTypeof(typeof.getSelectedItem().toString());
}
public void btnInsert1(View view){
ref1.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
DatabaseReference ref2=ref1.push();
String id=ref2.getKey();
request1 =new requests();
getValues();
ref1.child(id).setValue(request1);
Toast.makeText(FillRequestPage.this,"Data inserted....",Toast.LENGTH_SHORT).show();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
please help me
When sending data to the database, you do not need to use AddValueEventListener(..), you can just do this:
database = FirebaseDatabase.getInstance();
ref1 = database.getReference("requests");
DatabaseReference ref2=ref1.push();
String id=ref2.getKey();
request1 =new requests();
ref1.child(id).setValue(request1);
//some code may be missing
AddValueEventListener(..) is used to retrieve data from the database.
In Firebase database i have a directory called Global_downloads then inside there are a few children.
child.("Casting apps") which i can locate with in my app code using a String value called AppType.
the next child.("All cast") is the child i need. i can get it into firebase by using an onitem click with my listview. which then sends it to firebase in the form of a child.
but how can i locate the name for the child(Allcast) progmatically? so i can then get the number of downloads?
here is my code for my child listener
#Override
public void onChildAdded(final com.firebase.client.DataSnapshot dataSnapshot, String s) {
String counter = dataSnapshot.child("Global_downloads").child(Apptype).
child("I need this child").child("downloads").getValue(String.class);
Downloadscount.add(counter);
String[] arr3 = Downloadscount.toArray(new String[Downloadscount.size()]);
the rest of the items in the constructor are for other items in my listview
///my custom adapter where it returns the info to my listview
apkData = new dataListAdapter(mContext, arr, arr1, arr2, mrootRef, Apptype,arr3);
mlv.setAdapter(apkData);
apkData.notifyDataSetChanged();
mlv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
final Firebase ref = mrootRef.getRef();
//here is where i assign the name to firebase in my counter class which works
apkNames = AppNameList.get(i).toString(); //this is the name i want to send back to the top and use as a Child name.or can i get the child name another way.
gc = new Global_counter(ref,Apptype,apkNames);
gc.App_DownLoadCounter();
this is my listview there are more items on my list other than Allcast.
but all cast is the only item downloaded. if more items are pressed it adds that name to the list too. the text view you can see is the downloads im trying to add
To get the coresponding item that was downloaded, please use the following line of code inside onItemClick() method and then just use it inside your DatabaseReference.
String downloadName = (String) adapterView.getItemAtPosition(i);
Assuming that Global_downloads node is a direct child of your Firebase root and the value of downloads is of type Integer, to get the number of downloads please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference downloadsRef = rootRef.child("Global_downloads").child(Apptype).child(downloadName).child("downloads");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int downloads = dataSnapshot.getValue(Integer.class);
Log.d("TAG", downloads);
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
downloadsRef.addListenerForSingleValueEvent(eventListener);
Your output will be:
0
In your situation, the key is Apptype and the value is downloads.
I'm assuming Global_dowbloads under your root reference.
To get all the downloads with app name, you need to read the data as key->value
Like this
DatabaseReference mRef = FirebaseDatabase.getInstance().getReference();
mRef.child("Global_downloads").child(Apptype)
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot snapshot: dataSnapshot.getChildren()){
Log.v("app_name", snapshot.getKey());
Log.v("app_downloads", snapshot.getValue(String.class));
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});