I am trying to get a hang of the Android Architecture Library and i have been trying to display texts from retrofit via a ViewModel using Mutable LiveData on my Main Activity but i cant seem to do it, i would really appreciate some assistance.
Here is my Model Class
public class User {
#SerializedName("name")
#Expose
private String name;
#SerializedName("email")
#Expose
private String email;
#SerializedName("phone")
#Expose
private String phone;
public User() {
}
public String getUserName() {
return name;
}
public void setUserName(String name) {
this.name = name;
}
public String getUserEmail() {
return email;
}
public void setUserEmail(String email) {
this.email = email;
}
public String getUserPhone() {
return phone;
}
public void setUserPhone(String phone) {
this.phone = phone;
}
}
My View model
public class UserViewModel extends AndroidViewModel {
private NodeAuthService api;
private SharedPreferences pref;
private static MutableLiveData<List<User>> userDetails = new
MutableLiveData<>();
private Call<List<User>> call;
public UserViewModel(#NonNull Application application) {
super(application);
api = AuthRetrofitClient.getInstance().create(NodeAuthService.class);
}
private String email = pref.getString("email", "");
public void loadUser(){
call = api.getUser(email);
call.enqueue(new Callback<List<User>>() {
#Override
public void onResponse(Call<List<User>> call, Response<List<User>>
response) {
List<User> users = response.body();
}
#Override
public void onFailure(Call<List<User>> call, Throwable t) {
Log.d("USER",t.getMessage());
}
});
}
public MutableLiveData<List<User>> getUserDetails(){
return userDetails;
}
}
Simplified version of my MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
TextView navName = (TextView) findViewById(R.id.navigation_name);
TextView navEmail = (TextView) findViewById(R.id.navigation_email);
}
Kindly assist
In your viewModel
public void loadUser(){
call = api.getUser(email);
call.enqueue(new Callback<List<User>>() {
#Override
public void onResponse(Call<List<User>> call, Response<List<User>>
response) {
userDetails.postValue(response.body())
}
#Override
public void onFailure(Call<List<User>> call, Throwable t) {
Log.d("USER",t.getMessage());
}
});
}
And in your Activity observe the changes
yourVm.getUserDetails().observe(this, models -> {
if (models != null) {
for(int = 0; i<models.size();i++){
/*you will get your list here now iterate through list and get
your email_id here.*/
}
}
});
instead of this
List<User> users = response.body();
use this
userDetails.postValue(response.body())
also, remove static before livedata
inside activity oncreate() init your viewModel instance.
then viewModel.getUserDEtails().obsever(this, data-> // your stuff);
Related
In my Android app, I have a database repository to contact Firebase Realtime Database and a service layer with some methods. My SaveUserProfile method works but I keep getting a null pointer on my GetUserFromUid.
The 'user' object it returns is null and I don't know why. The node in my DB is called "users" (all lowercase) and I want to retrieve a user as a model via their userId and display the name and email onscreen.
Can anybody see where I'm going wrong?
My DbContext:
public class DbContext implements IDbContext {
User user = null;
Context context;
DatabaseReference databaseUsers = FirebaseDatabase.getInstance().getReference("users");
public DbContext(Context context){
super();
this.context = context;
}
#Override
public void AddUserAccount(User user1) {
databaseUsers.child(user1.userId).setValue(user1);
}
#Override
public User GetUserFromFirebase(String uid) {
databaseUsers.child(uid)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
user = dataSnapshot.getValue(User.class);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
return user;
}
My DbService:
public class DbService implements IDbService {
//instance of DbContext for firebase handling
private DbContext dbContext;
public DbService(Context context){
super();
dbContext = new DbContext(context);
}
#Override
public User SaveUserProfile(User u) {
dbContext.AddUserAccount(u);
return u;
}
#Override
public User GetUserFromUid(String uid) {
User user = dbContext.GetUserFromFirebase(uid);
return user;
}
My User model:
public class User {
public String userId;
public String name;
public String email;
public String account;
//constructor required for calls to DataSnapshot.getValue(User.class)
public User(){
}
public User(String userId, String name, String email, String account) {
this.userId = userId;
this.name = name;
this.email = email;
this.account = account;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
My activity where I want to display the users' details:
public class DetailsActivity extends AppCompatActivity {
//tag
private static final String TAG = DetailsActivity.class.getSimpleName();
//firebase auth
private FirebaseAuth mAuth;
//variables
private TextView inputName, inputEmail;
private DatabaseReference mFirebaseDatabase;
private String userId;
public String currentUserAccount;
public String teacherAccountNav = "Teacher";
public User userDetails;
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
inputName = findViewById(R.id.nameTextView);
inputEmail = findViewById(R.id.emailTextView);
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
assert user != null;
userId = user.getUid();
getUserDetails(userId);
inputName.setText(userDetails.name);
inputEmail.setText(userDetails.email);
}
public User getUserDetails(String uid){
DbService dbService = new DbService(this);
userDetails = dbService.GetUserFromUid(uid);
return userDetails;
}
EDITS BELOW
My callback:
public interface Callback {
void myResponseCallback(User user);
}
My EDITED DbContext:
public class DbContext implements IDbContext {
User user = null;
Context context;
DatabaseReference databaseUsers = FirebaseDatabase.getInstance().getReference("users");
public DbContext(Context context) {
this.context = context;
}
#Override
public void AddUserAccount(User user1) {
databaseUsers.child(user1.userId).setValue(user1);
}
#Override
public void GetUserFromFirebase(String uid, final Callback callback) {
databaseUsers.child(uid)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
user = dataSnapshot.getValue(User.class);
callback.myResponseCallback(user);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
My EDITED DbService:
public class DbService implements IDbService {
//instance of DbContext for firebase handling
public DbContext dbContext;
public DbService(Context context){
super();
dbContext = new DbContext(context);
}
#Override
public User SaveUserProfile(User u) {
dbContext.AddUserAccount(u);
return u;
}
#Override
public User GetUserFromUid(String uid) {
final User[] user1 = {new User()};
dbContext.GetUserFromFirebase(uid, new Callback() {
#Override
public void myResponseCallback(User user) {
user1[0] = user;
}
});
return user1[0];
}
My EDITED Activity:
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
inputName = findViewById(R.id.nameTextView);
inputEmail = findViewById(R.id.emailTextView);
FirebaseDatabase mFirebaseInstance = FirebaseDatabase.getInstance();
//reference to 'users' node
mFirebaseDatabase = mFirebaseInstance.getReference("users");
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
assert user != null;
userId = user.getUid();
getUserFromFirebase(userId);
}
public void getUserFromFirebase(String uid){
userDetails = (new DbService(this)).GetUserFromUid(uid);
inputEmail.setText(userDetails.email);
inputName.setText(userDetails.name);
}
Debug BEFORE edits:
Debug AFTER edits:
As you can see from the debug, before the callback interface, userDetails was null. After the interface implementation, userDetails is not null but all of the object values are null. I don't know why this is as they are filled in the database. Any ideas?
Good night everybody.
I need to do a POST request and I'm using Retrofit 2 to do this.
But the Api I'm consuming does not give me these parameters in the API response, just in the body.
Api Response
I already searched in some places but I did not find anything that could help me.
My interface Class
public interface LoginApi {
#POST("api/login")
Call<UserAccount> doLogin(#Body Login login);
}
My Model Class
public class Login {
public String user;
public String password;
}
My API response class
public class UserAccount {
#SerializedName("userId")
#Expose
private Integer userId;
#SerializedName("name")
#Expose
private String name;
#SerializedName("bankAccount")
#Expose
private String bankAccount;
#SerializedName("agency")
#Expose
private String agency;
#SerializedName("balance")
#Expose
private Double balance;
}
My call class
public class LoginPresenter {
private LoginView loginView;
private ServiceConfig serviceConfig;
public LoginPresenter() {
this.loginView = loginView;
if (this.serviceConfig == null) {
this.serviceConfig = new ServiceConfig();
}
}
public void doLogin(Login login) {
serviceConfig
.login()
.doLogin(login)
.enqueue(new Callback<UserAccount>() {
#Override
public void onResponse(Call<UserAccount> call, Response<UserAccount> response) {
UserAccount userAccount = response.body();
assert userAccount != null;
Log.e("Agency:",userAccount.getAgency());
Log.e("BankAccount:", userAccount.getBankAccount());
Log.e("Name:", userAccount.getName());
}
#Override
public void onFailure(Call<UserAccount> call, Throwable t) {
Log.d("Erro", t.getMessage());
}
});
}
}
My Activity
public class LoginActivity extends Activity implements LoginView {
private EditText edtUser, edtPassword;
private Button btnLogin;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
init();
}
private void init() {
edtUser = findViewById(R.id.edt_user);
edtPassword = findViewById(R.id.edt_password);
btnLogin = findViewById(R.id.btn_login);
final LoginPresenter loginPresenter = new LoginPresenter();
final Login login = new Login();
login.user = edtUser.getText().toString();
login.password = edtPassword.getText().toString();
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
loginPresenter.doLogin(login);
}
});
}
#Override
public void userAccount(List<UserAccount> userAccount) {
}
}
I hope I have made my problem clear and that someone who has been through it can help me.
Appreciate.
Pass #Body JsonObject body instead of #Body Login login
Here is full code:
Your interface will be:
public interface LoginApi {
#POST("api/login")
Call<UserAccount> doLogin(#Body JsonObject body);
}
How to Create JsonObject :
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("user", userValue);
jsonObject.addProperty("password", passwordValue);
Pass it from your activity to presenter.
Hope it will works for you.
Thank you.
Pass Like This:-
You Interface
public interface ApiInterface {
String URL_BASE = "Base Url";
#Headers("Content-Type: application/json")
#POST("login")
Call<User> getUser(#Body String body);
}
Activity
public class SampleActivity extends AppCompatActivity implements Callback<User> {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ApiInterface.URL_BASE)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiInterface apiInterface = retrofit.create(ApiInterface.class);
// prepare call in Retrofit 2.0
try {
JSONObject paramObject = new JSONObject();
paramObject.put("email", "sample#gmail.com");
paramObject.put("pass", "4384984938943");
Call<User> userCall = apiInterface.getUser(paramObject.toString());
userCall.enqueue(this);
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onResponse(Call<User> call, Response<User> response) {
}
#Override
public void onFailure(Call<User> call, Throwable t) {
}
}
I have a web service link for token login. But in this link, there is no "/" at the end of link. And android studio make error called baseUrl must end in /. When I put / it don't get token and say token is not truth :( because the link is not correct in my think. I use retrofit2library. Please help me to solve it.
MainActivity.java
public class MainActivity extends AppCompatActivity {
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl("http://website.net/token")
.addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.build();
UserClient userClient = retrofit.create(UserClient.class);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
Button loginButton=(Button)findViewById(R.id.btn_login);
loginButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
login();
/* Intent intentLogin=new Intent(MainActivity.this,MainPageActivity.class);
startActivity(intentLogin);*/
}
});
}
private static String token;
private void login() {
Login login = new Login("abcd", "1234");
Call<User> call = userClient.login(login);
call.enqueue(new Callback<User>() {
#Override
public void onResponse(Call<User> call, Response<User> response) {
if (response.isSuccessful()){
Toast.makeText(MainActivity.this, response.body().getToken(), Toast.LENGTH_SHORT).show();
token = response.body().getToken();
}
else {
Toast.makeText(MainActivity.this, "Token is not truth :(", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<User> call, Throwable t) {
Toast.makeText(MainActivity.this, "error!", Toast.LENGTH_SHORT).show();
}
});
}
}
`Login.java
public class Login {
private String user;
private String password;
public Login(String user, String password) {
this.user = user;
this.password = password;
}
}
User.java
public class User {
private int id;
private String email;
private String token;
public int getId(){
return id;
}
public void setId(){
this.id = id;
}
public String getEmail(){
return email;
}
public void setEmail(String email){
this.email = email;
}
public String getToken(){return token;}
public void setToken(String token){this.token = token;}
}
UserClient.java
import com.squareup.okhttp.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.POST;
public interface UserClient {
#POST("Login")
Call<User> login(#Body Login login);
// #GET("secretinfo")
// Call<ResponseBody> getSecret(#Header("Authorization") String authToken);
}
Use upto this in
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl("http://website.net/")
.addConverterFactory(GsonConverterFactory.create());
and in the UserClient interface class
public interface UserClient {
#POST("token") Call<User> login(#Body Login login);
}
I'm trying to retrieve values from the database to display on views but im getting this crash right here
FATAL EXCEPTION: main
Process: com.example.ahmad.carrental, PID: 15975
com.google.firebase.database.DatabaseException: Failed to convert a value of type java.lang.String to long
at com.google.android.gms.internal.zzear.zzb(Unknown Source)
at com.google.android.gms.internal.zzear.zza(Unknown Source)
at com.google.android.gms.internal.zzear.zzb(Unknown Source)
at com.google.android.gms.internal.zzeas.zze(Unknown Source)
at com.google.android.gms.internal.zzear.zzb(Unknown Source)
at com.google.android.gms.internal.zzear.zza(Unknown Source)
at com.google.firebase.database.DataSnapshot.getValue(Unknown Source)
at com.example.ahmad.carrental.Utilities.FirebaseUtilities.getCarData(FirebaseUtilities.java:178)
at com.example.ahmad.carrental.CarPost.CreatePostActivity$1$1.onDataChange(CreatePostActivity.java:100)
at com.google.android.gms.internal.zzduz.zza(Unknown Source)
at com.google.android.gms.internal.zzdwu.zzbvb(Unknown Source)
at com.google.android.gms.internal.zzdxa.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:761)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:156)
at android.app.ActivityThread.main(ActivityThread.java:6605)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:999)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:889)
The classes are as follows
Car Model
public class Car {
private String brand;
private String id;
private int price;
private String model;
private long distance;
private String status;
private String picture;
private String location;
private String description;
public Car() {
}
public Car(String brand, String id, int price, String model, long distance, String status, String picture, String location, String description) {
this.brand = brand;
this.id = id;
this.price = price;
this.model = model;
this.distance = distance;
this.status = status;
this.picture = picture;
this.location = location;
this.description = description;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public long getDistance() {
return distance;
}
public void setDistance(long distance) {
this.distance = distance;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getPicture() {
return picture;
}
public void setPicture(String picture) {
this.picture = picture;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
User Model
public class User {
private String email;
private String id;
private String name;
private int phonenumber;
public User(String email, String id, String name,int phonenumber) {
this.email = email;
this.id = id;
this.name = name;
this.phonenumber = phonenumber;
}
public User(){
}
public int getPhonenumber() {
return phonenumber;
}
public void setPhonenumber(int phonenumber) {
this.phonenumber = phonenumber;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Database Querying Function
public Car getCarData(DataSnapshot dataSnapshot) {
Log.i(TAG,"getCardData: Getting car data from database");
Car data = new Car();
for(DataSnapshot ds :dataSnapshot.getChildren()){
if(ds.getKey().equals(context.getString(R.string.dbname_car_post))){
try{
data.setId(ds.child(userID).getValue(Car.class).getId());
data.setBrand(ds.child(userID).getValue(Car.class).getBrand());
data.setDescription(ds.child(userID).getValue(Car.class).getDescription());
data.setModel(ds.child(userID).getValue(Car.class).getModel());
data.setDistance(ds.child(userID).getValue(Car.class).getDistance());
data.setPicture(ds.child(userID).getValue(Car.class).getPicture());
data.setStatus(ds.child(userID).getValue(Car.class).getStatus());
data.setLocation(ds.child(userID).getValue(Car.class).getLocation());
data.setPrice(ds.child(userID).getValue(Car.class).getPrice());
}catch (NullPointerException e){
Log.d(TAG, "getCarData: NullPointerException : " + e.getMessage());
}
}
}
return data;
}
Activity that im retrieving the data from
CreateCarPost Activity
public class CreatePostActivity extends AppCompatActivity implements CreatePostView,AdapterView.OnItemSelectedListener{
//Activity Tag
private static final String TAG ="CreateCarPost";
//Spinners
Spinner statusSpinner;
Spinner brandSpinner;
//Adapter of spinners
ArrayAdapter mArrayAdapter;
ArrayAdapter mArrayAdapter2;
//views
private TextView tvDistance;
private EditText etDistance;
private AutoCompleteTextView etCarLocation;
private CircleImageView civPicture;
private EditText etPrice;
private EditText etDescription;
private EditText etModel;
private ImageView checkButton;
//Strings
private String carLoactionStr;
private String carBrandStr;
private String carStatusStr;
//layout containg the views
private LinearLayout layoutContainer;
//To adjust dynamic views margins
LinearLayout.LayoutParams layoutParamsTv,layoutParamsEt;
//Firebase
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthStateListener;
private FirebaseDatabase mFirebaseDatabase;
private DatabaseReference mDatabaseReference;
private ValueEventListener singleValueEventListener;
private FirebaseUtilities mFirebaseUtilities;
Context mContext;
CreatePostPresenter createPostPresenter;
private Car car;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_post);
initialization();
setupFirebaseAuth();
setUpLocationSpinner();
//Assigning Car object with its data from database.
io.reactivex.Observable.create(new ObservableOnSubscribe() {
#Override
public void subscribe(ObservableEmitter emitter) throws Exception {
singleValueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
car = mFirebaseUtilities.getCarData(dataSnapshot);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e(TAG, "CANCELLED.");
}
};
mDatabaseReference.addValueEventListener(singleValueEventListener);
}
}).unsubscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe();
checkButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
createPostPresenter.onSaveChanges(car);
}
});
}
//initalizing everything necessary here
public void initialization(){
mContext = getApplicationContext();
createPostPresenter = new CreatePostPresenter(this,this);
//Adapter set up for spinners
mArrayAdapter2 = ArrayAdapter.createFromResource(this,R.array.car_brands,android.R.layout.simple_spinner_item);
mArrayAdapter = ArrayAdapter.createFromResource(this,R.array.car_status_array,android.R.layout.simple_spinner_item);
//Status spinner set up
statusSpinner = findViewById(R.id.createPostCarStatusSpinner_ID);
statusSpinner.setAdapter(mArrayAdapter);
statusSpinner.setOnItemSelectedListener(this);
//Brand spinner set up
brandSpinner = findViewById(R.id.createPostCarBrandSpinner_ID);
brandSpinner.setAdapter(mArrayAdapter2);
brandSpinner.setOnItemSelectedListener(this);
layoutContainer = findViewById(R.id.createPostLinearLayout_ID);
tvDistance = new TextView(this);
tvDistance.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
tvDistance.setText("Distance Travelled");
etDistance = new EditText(this);
etDistance.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
//margin settings editText
layoutParamsEt = (LinearLayout.LayoutParams)etDistance.getLayoutParams();
layoutParamsEt.setMargins(0,10,0,0);
etDistance.setLayoutParams(layoutParamsEt);
//margin settings textView
layoutParamsTv = (LinearLayout.LayoutParams)tvDistance.getLayoutParams();
layoutParamsTv.setMargins(0,10,0,0);
tvDistance.setLayoutParams(layoutParamsTv);
etCarLocation = findViewById(R.id.createPostCarLocation_ID);
etDescription = findViewById(R.id.createPostCarDes_ID);
etPrice = findViewById(R.id.createPostCarPrice_ID);
etModel = findViewById(R.id.createPostCarModel_ID);
checkButton = findViewById(R.id.check_ID);
mFirebaseUtilities = new FirebaseUtilities(this);
}
private void setUpLocationSpinner() {
ArrayAdapter<String> listOfCities = new ArrayAdapter<>(getBaseContext(),
android.R.layout.simple_list_item_1, getResources().getStringArray(R.array.TR_cities));
//--- to ensure user is restricted to selections from drop-down menu
etCarLocation.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
carLoactionStr = etCarLocation.getAdapter().getItem(position).toString();
}
});
etCarLocation.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
for (int i = 0; i < etCarLocation.getAdapter().getCount(); i++) {
if (etCarLocation.getText().toString().equals(etCarLocation.getAdapter().getItem(i))) {
carLoactionStr = etCarLocation.getAdapter().getItem(i).toString();
} else
carLoactionStr = null;
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
//start autocomplete after 1 letter
etCarLocation.setThreshold(1);
etCarLocation.performCompletion();
etCarLocation.setAdapter(listOfCities);
}
/**
* Listener for car status spinner
* #param parent
* #param view
* #param position
* #param id
*/
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Spinner spinner = (Spinner)parent;
if(spinner.getId() == R.id.createPostCarStatusSpinner_ID){
TextView textView = (TextView) view;
carStatusStr = textView.getText().toString();
addDynamicViews(position);
}
else if(spinner.getId() == R.id.createPostCarBrandSpinner_ID){
TextView textView = (TextView) view;
carBrandStr = textView.getText().toString();
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
/**
* Dynamic views creation done by handling user spinner selection for first hand or second hand car status.
*#param position: position of selected value from spinner
*/
public void addDynamicViews(int position){
if(position == 1){
layoutContainer.addView(tvDistance);
layoutContainer.addView(etDistance);
}
else if(position == 0){
mFirebaseUtilities.removeNodeDynamically();
layoutContainer.removeView(tvDistance);
layoutContainer.removeView(etDistance);
}
}
#Override
public void setBrand(String brand) {
}
#Override
public void setPrice(int price) {
}
#Override
public void setLocation(String location) {
}
#Override
public void setDescription(String description) {
}
#Override
public void setModel(String model) {
}
#Override
public void setDistance(long distance) {
}
#Override
public void setStatus(String status) {
}
#Override
public void setPicture(String picture) {
}
#Override
public String getBrand() {
return carBrandStr;
}
#Override
public String getDescription() {
return etDescription.getText().toString();
}
#Override
public String getLocation() {
return carLoactionStr;
}
#Override
public String getModel() {
return etModel.getText().toString();
}
#Override
public String getStatus() {
return carStatusStr;
}
#Override
public String getPicture() {
return null;
}
#Override
public int getPrice() {
String priceViewTemp = etPrice.getText().toString();
if (priceViewTemp.equals("")) {
return 0;
} else {
return Integer.valueOf(etPrice.getText().toString());
}
}
#Override
public long getDistance() {
String distanceViewTemp = etDistance.getText().toString();
if (distanceViewTemp.equals("")) {
return 0;
} else {
return Integer.valueOf(etDistance.getText().toString());
}
}
/*************************************** Firebase *******************************************/
private void setupFirebaseAuth() {
mAuth = FirebaseAuth.getInstance();
mFirebaseDatabase = FirebaseDatabase.getInstance();
mDatabaseReference = mFirebaseDatabase.getReference();
mAuthStateListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
//User is signed in
Log.d(TAG, "onAuthStateChanged: user signed in : " + user.getUid());
} else {
//User is signed out
Log.d(TAG, "onAuthStateChanged: user signed out");
}
}
};
mDatabaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public void onPause() {
super.onPause();
if (singleValueEventListener != null) {
mDatabaseReference.removeEventListener(singleValueEventListener);
}
}
#Override
public void onResume(){
super.onResume();
mDatabaseReference.addListenerForSingleValueEvent(singleValueEventListener);
}
}
Firebase Structure
Firebase Structure
Haven't read if much, but i first noticed something here.
for(DataSnapshot ds :dataSnapshot.getChildren()){
if(ds.getKey().equals(context.getString(R.string.dbname_car_post))){
try{ }
The key you're trying to retrieve is an Object. So i would propose we convert it string first, sample down here.
for(DataSnapshot ds :dataSnapshot.getChildren()){
Object myKey=ds.getKey;
if(myKey.toString().equals(context.getString(R.string.dbname_car_post))){
try{ }
}}
Let me know what happens next!
If my database is still loading, then show loading dialog. That what I want to make my chatapp works. I found out that my problem will solve by overriding onDataChanged() in my FirebaseRecyclerAdapter like this code below
new FirebaseRecyclerAdapter(...) {
#Override
protected void populateViewHolder(...) {...}
#Override
protected void onDataChanged() {
}
};
but the problem is I can't override the onDataChanged() to my Adapter.
How can i fix this problem? please see my Screenshot below.
UPDATED:
This is my whole code related to my problem (other codes are not necessary to post).
public void btn_discussion() {
FRRA = new FirebaseRecyclerAdapter<Message, MessageViewHolder>(
Message.class,
R.layout.discussion_q_and_answer,
ActivityDiscussion.MessageViewHolder.class,
MyDatabase
) {
#Override
protected void populateViewHolder(ActivityDiscussion.MessageViewHolder viewHolder, Message model, int position) {
viewHolder.setContent(model.getContent());
viewHolder.setUsername(model.getUsername());
viewHolder.setTime(myConstructor.LongToDate(model.getTime()));
}
#Override
protected void onDataChanged() {
//Write something here
}
};
msgList.setAdapter(FRRA);
msgList.smoothScrollToPosition(FRRA.getItemCount());
}
RecyclerView.ViewHolder
public static class MessageViewHolder extends RecyclerView.ViewHolder {
View view;
public MessageViewHolder(View itemView) {
super(itemView);
this.view = itemView;
}
private void setContent(String content) {
TextView msg = view.findViewById(R.id.comment);
msg.setText(content);
}
private void setUsername(String username) {
TextView msg = view.findViewById(R.id.tv_user);
msg.setText(username);
}
private void setTime(String time) {
TextView msg = view.findViewById(R.id.tv_time);
msg.setText(time);
}
}
Getter and Setter
Message.java
public class Message {
private String content;
private String Username;
private String time;
public Message() {}
public Message(String mcontent, String musername, String mtime) {
this.content = mcontent;
this.Username = musername;
this.time = mtime;
}
public String getContent() {
return content;
}
public void setContent(String message) {
this.content = message;
}
public String getUsername() {
return Username;
}
public void setUsername(String Username) {
this.Username = Username;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
}
You are using an older version of firebaseui and in the older versions onDataChanged was not in the override methods. You can see that by clicking ALT+ INS to see all override methods belonging to this class.
You need to use the latest one which is this:
implementation 'com.firebaseui:firebase-ui-database:3.1.1'
and then you can use onDataChanged and other methods. When you upgrade you will have to use FirebaseRecyclerOptions also, for more info check this guide here:
FirebaseUI for Realtime Database