rahul singhania rahul singhania - 25 days ago 30
Android Question

com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type class object

I'm getting android run time exception for this java class:
I am not getting where the problem is occurring, I have tried almost all similar questions' answers but no help! Also, I have tried to run the code by commenting almost all the unrelated functions, but that didn't rule out the error too.

public class MainActivity extends AppCompatActivity
implements GoogleApiClient.OnConnectionFailedListener {

private String intentsChild;
private String curFirebaseLocation;
public static final String ANONYMOUS = "anonymous";
private static final String TAG = "MainActivity";
private FirebaseAuth mFirebaseAuth;
private FirebaseUser mFirebaseUser;
private String mUsername;
private String mPhotoUrl;
private GoogleApiClient mGoogleApiClient;
private Button mSendButton;
private RecyclerView mMessageRecyclerView;
private LinearLayoutManager mLinearLayoutManager;
private ProgressBar mProgressBar;
private EditText mMessageEditText;
private DatabaseReference mFirebaseDatabaseReference;
private FirebaseRecyclerAdapter<FriendlyMessage, MessageViewHolder>
mFirebaseAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setStatusBarTranslucent(true);

// Set default username is anonymous.
mUsername = ANONYMOUS;
// Initialize Firebase Auth
mFirebaseAuth = FirebaseAuth.getInstance();
mFirebaseUser = mFirebaseAuth.getCurrentUser();

//initialize facebook app activation
FacebookSdk.sdkInitialize(getApplicationContext());
AppEventsLogger.activateApp(getApplication());

if (mFirebaseUser == null) {
// Not signed in, launch the Sign In activity
startActivity(new Intent(this, SignInActivity.class));
finish();
return;
} else {
mUsername = mFirebaseUser.getDisplayName();
if (mFirebaseUser.getPhotoUrl() != null) {
mPhotoUrl = mFirebaseUser.getPhotoUrl().toString();
}
}

mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API)
.build();

// Initialize ProgressBar and RecyclerView.
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
mMessageRecyclerView = (RecyclerView) findViewById(R.id.messageRecyclerView);
mLinearLayoutManager = new LinearLayoutManager(this);
mLinearLayoutManager.setStackFromEnd(true);
mMessageRecyclerView.setLayoutManager(mLinearLayoutManager);
mFirebaseDatabaseReference = FirebaseDatabase.getInstance().getReference();

curFirebaseLocation = "users/" + mFirebaseAuth.getCurrentUser().getUid().trim() + "/messages";
intentsChild = "users/" + mFirebaseAuth.getCurrentUser().getUid().trim() + "/intents";



Toast.makeText(this, "users/" + mFirebaseAuth.getCurrentUser().getUid().trim(), Toast.LENGTH_SHORT).show();

// if(mFirebaseDatabaseReference.child(curFirebaseLocation).getParent() == null){
// Toast.makeText(this, curFirebaseLocation + " already exists.", Toast.LENGTH_SHORT).show();
IntentMessage tempintent = new IntentMessage("", "");
FriendlyMessage tempmessage = new FriendlyMessage("Hello, I'm Ed, your personal assistant cum friend",
"Ed", "https://cdn1.iconfinder.com/data/icons/user-pictures/100/male3-512.png", "1476880306");
mFirebaseDatabaseReference.child(curFirebaseLocation).setValue(tempmessage);
mFirebaseDatabaseReference.child(intentsChild).setValue(tempintent);
// }
Toast.makeText(this, curFirebaseLocation, Toast.LENGTH_SHORT).show();



// New child entries
mFirebaseAdapter = new FirebaseRecyclerAdapter<FriendlyMessage,
MessageViewHolder>(
FriendlyMessage.class,
R.layout.item_message,
MessageViewHolder.class,
mFirebaseDatabaseReference.child(curFirebaseLocation)) {


@Override
protected void populateViewHolder(MessageViewHolder viewHolder,
FriendlyMessage friendlyMessage, int position) {
mProgressBar.setVisibility(ProgressBar.INVISIBLE);
viewHolder.messageTextView.setText(friendlyMessage.getText());
viewHolder.messengerTextView.setText(friendlyMessage.getName());
if (friendlyMessage.getPhotoUrl() == null) {
viewHolder.messengerImageView
.setImageDrawable(ContextCompat
.getDrawable(MainActivity.this,
tod));
} else {
Glide.with(MainActivity.this)
.load(friendlyMessage.getPhotoUrl())
.into(viewHolder.messengerImageView);
}
if (friendlyMessage.getName().equals("Ed")){
//TODO : Do this as it is necessary
// viewHolder.diffForRecSend.setBackgroundColor(ContextCompat.getColor(MainActivity.this, R.color.white));
// viewHolder.diffForRecSend.setBackgroundResource(R.drawable.abcd123);
}
else {
//TODO : Do this as it is necessary
// viewHolder.diffForRecSend.setBackgroundColor(ContextCompat.getColor(MainActivity.this, R.color.colorAccent));
// viewHolder.diffForRecSend.setBackgroundResource(R.drawable.abcd1234);
}
}
};

mFirebaseDatabaseReference.child(intentsChild).addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {

}

@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
IntentMessage newIntentMessage = dataSnapshot.getValue(IntentMessage.class);
String name = newIntentMessage.getIntentName();
String fields = newIntentMessage.getIntentFields();
if (name.equals("") || fields.equals(""))
return;
IntentMessage temp = new IntentMessage("", "");
mFirebaseDatabaseReference.child(intentsChild).child("-KUWmGwxVe0HCYtYWfdI").setValue(temp);
// IntentFiringActivity newIntentFiringActivity;
Log.d(TAG, "onChildUpdated: " + name + fields);
System.out.println("onChildUpdated: " + name + fields);
if (name.equals("gmail"))
fireGmailIntent(fields.split("\\$"));
else if (name.equals("alarm1"))
fireAlarmIntent(fields.split("\\$"));
else if (name.equals("alarm2"))
fireAlarmIntent2(fields.split("\\$"));
// newIntentFiringActivity = new IntentFiringActivity(name, fields);
}

@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
IntentMessage newIntentMessage = dataSnapshot.getValue(IntentMessage.class);
Log.d(TAG, "onChildRemoved: " + newIntentMessage.getIntentName() + newIntentMessage.getIntentFields());
System.out.println("onChildRemoved: " + newIntentMessage.getIntentName() + newIntentMessage.getIntentFields());
}

@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}

@Override
public void onCancelled(DatabaseError databaseError) {
}
});


mFirebaseAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
int friendlyMessageCount = mFirebaseAdapter.getItemCount();
int lastVisiblePosition =
mLinearLayoutManager.findLastCompletelyVisibleItemPosition();
// If the recycler view is initially being loaded or the
// user is at the bottom of the list, scroll to the bottom
// of the list to show the newly added message.
if (lastVisiblePosition == -1 ||
(positionStart >= (friendlyMessageCount - 1) &&
lastVisiblePosition == (positionStart - 1))) {
mMessageRecyclerView.scrollToPosition(positionStart);
}
}
});

mMessageRecyclerView.setLayoutManager(mLinearLayoutManager);
mMessageRecyclerView.setAdapter(mFirebaseAdapter);
mMessageEditText = (EditText) findViewById(R.id.messageEditText);

mMessageEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}

@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (charSequence.toString().trim().length() > 0) {
mSendButton.setEnabled(true);
} else {
mSendButton.setEnabled(false);
}
}

@Override
public void afterTextChanged(Editable editable) {
}
});

mSendButton = (Button) findViewById(R.id.sendButton);

mSendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Long tsLong = (System.currentTimeMillis() / 1000);
String ts = tsLong.toString();
FriendlyMessage friendlyMessage = new
FriendlyMessage(mMessageEditText.getText().toString(),
mUsername,
mPhotoUrl,
ts);
mFirebaseDatabaseReference.child(curFirebaseLocation)
.push().setValue(friendlyMessage);
mMessageEditText.setText("");
}
});
}

private void fireAlarmIntent(String[] intentFields) {
int hours = Integer.parseInt(intentFields[0].trim());
int minutes;
if(intentFields[1].trim().equals("")){
minutes = 0;
}
else {
minutes = Integer.parseInt(intentFields[1].trim());
}
Intent i = new Intent(AlarmClock.ACTION_SET_ALARM);
i.putExtra(AlarmClock.EXTRA_SKIP_UI, true);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra(AlarmClock.EXTRA_HOUR, hours);
i.putExtra(AlarmClock.EXTRA_MINUTES, minutes);
int temp1 = 1;
startActivityForResult(i, temp1);
String temp = "Alarm set for " + hours + " : " + minutes;
Log.d(TAG, temp);
// Toast.makeText(this, temp, Toast.LENGTH_SHORT).show();
}

private void fireAlarmIntent2(String[] intentFields) {
int hours = Integer.parseInt(intentFields[0].trim());
int curhours = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
int finalhours = (hours + curhours) % 24;
int curmin = Calendar.getInstance().get(Calendar.MINUTE);
Intent i = new Intent(AlarmClock.ACTION_SET_ALARM);
i.putExtra(AlarmClock.EXTRA_SKIP_UI, true);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra(AlarmClock.EXTRA_HOUR, finalhours);
i.putExtra(AlarmClock.EXTRA_MINUTES, curmin);
int temp1 = 1;
startActivityForResult(i, temp1);
String temp = "Alarm set for " + finalhours + " : " + curmin;
Log.d(TAG, temp);
Log.d(TAG, "currentHours: " + curhours + " and received from server : " + hours + " hence total is : " + finalhours);
// Toast.makeText(this, temp, Toast.LENGTH_SHORT).show();

}

private void fireGmailIntent(String[] intentFields) {
String[] email = new String[1];
email[0] = intentFields[0];
Log.d(TAG, "My unique log " + email[0]);
String subject = intentFields[1];
String body = intentFields[2];
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setType("message/rfc822");
intent.setData(Uri.parse("mailto:"));
intent.putExtra(Intent.EXTRA_EMAIL, email);
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
intent.putExtra(Intent.EXTRA_TEXT, body);
Log.d(TAG, "My unique log " + email[0] + "__" + subject + "__" + body);
if (intent.resolveActivity(getPackageManager()) != null) {
int temp = 4;
startActivityForResult(intent, temp);
Log.d(TAG, "My unique log " + email[0] + "__" + subject + "__" + body + "again");
}
}

protected void setStatusBarTranslucent(boolean makeTranslucent) {
if (makeTranslucent) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
} else {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
// Firebase instance variables

@Override
public void onStart() {
super.onStart();
// Check if user is signed in.
// TODO: Add code to check if user is signed in.
}

@Override
public void onPause() {
super.onPause();
}

@Override
public void onResume() {
super.onResume();
}

@Override
public void onDestroy() {
super.onDestroy();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
return true;
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
startActivity(new Intent(this, SignInActivity.class));
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.sign_out_menu:
mFirebaseAuth.signOut();
LoginManager.getInstance().logOut();
FirebaseAuth.getInstance().signOut();
Auth.GoogleSignInApi.signOut(mGoogleApiClient);
mUsername = ANONYMOUS;
startActivity(new Intent(this, SignInActivity.class));
return true;
default:
return super.onOptionsItemSelected(item);
}
}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
// An unresolvable error has occurred and Google APIs (including Sign-In) will not
// be available.
Log.d(TAG, "onConnectionFailed:" + connectionResult);
Toast.makeText(this, "Google Play Services error.", Toast.LENGTH_SHORT).show();
}

public static class MessageViewHolder extends RecyclerView.ViewHolder {
public TextView messageTextView;
public TextView messengerTextView;
public CircleImageView messengerImageView;
public LinearLayout diffForRecSend;

public MessageViewHolder(View v) {
super(v);
messageTextView = (TextView) itemView.findViewById(R.id.messageTextView);
messengerTextView = (TextView) itemView.findViewById(R.id.messengerTextView);
messengerImageView = (CircleImageView) itemView.findViewById(R.id.messengerImageView);
diffForRecSend = (LinearLayout) itemView.findViewById(R.id.message_main_id);
}
}

}


This is the logcat error:

Process: com.google.firebase.codelab.friendlychat, PID: 20107
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type com.google.firebase.codelab.friendlychat.FriendlyMessage
at com.google.android.gms.internal.zzaln.zzd(Unknown Source)
at com.google.android.gms.internal.zzaln.zzb(Unknown Source)
at com.google.android.gms.internal.zzaln.zza(Unknown Source)
at com.google.firebase.database.DataSnapshot.getValue(Unknown Source)
at com.firebase.ui.database.FirebaseRecyclerAdapter.parseSnapshot(FirebaseRecyclerAdapter.java:147)
at com.firebase.ui.database.FirebaseRecyclerAdapter.getItem(FirebaseRecyclerAdapter.java:136)
at com.firebase.ui.database.FirebaseRecyclerAdapter.onBindViewHolder(FirebaseRecyclerAdapter.java:176)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:5453)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:5486)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4723)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4599)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1988)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1384)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1347)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:549)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3003)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2881)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3265)
at android.view.View.layout(View.java:16969)
at android.view.ViewGroup.layout(ViewGroup.java:5583)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1189)
at android.view.View.layout(View.java:16969)
at android.view.ViewGroup.layout(ViewGroup.java:5583)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:396)
at android.widget.FrameLayout.onLayout(FrameLayout.java:333)
at android.view.View.layout(View.java:16969)
at android.view.ViewGroup.layout(ViewGroup.java:5583)
at android.support.v7.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:437)
at android.view.View.layout(View.java:16969)
at android.view.ViewGroup.layout(ViewGroup.java:5583)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:396)
at android.widget.FrameLayout.onLayout(FrameLayout.java:333)
at android.view.View.layout(View.java:16969)
at android.view.ViewGroup.layout(ViewGroup.java:5583)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:2001)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1844)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1753)
at android.view.View.layout(View.java:16969)
at android.view.ViewGroup.layout(ViewGroup.java:5583)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:396)
at android.widget.FrameLayout.onLayout(FrameLayout.java:333)
at com.android.internal.policy.PhoneWindow$DecorView.onLayout(PhoneWindow.java:2728)
at android.view.View.layout(View.java:16969)
at android.view.ViewGroup.layout(ViewGroup.java:5583)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2552)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2255)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1321)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6708)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:894)
at android.view.Choreographer.doCallbacks(Choreographer.java:696)
at android.view.Choreographer.doFrame(Choreographer.java:631)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:880)
at android.os.Handler.handleCallback(Handler.java:822)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Loop


The following is just a snapshot of my json structure for reference:

{
"users" : {
"ERyWg81WxrXUb0sjsu9hv9T7K0E3" : {
"intents" : {
"intentName" : "",
"intentValue" : ""
},
"messages" : {
"-KViVgc7ZG051eMXP0-5" : {
"name" : "Ed",
"text" : "Hello, I'm Ed, your personal assistant cum friend",
"timestamp" : "1476880306"
}
}
},
"Y9UNlizDSobddO8cdq7K4ChipYa2" : {
"intents" : {
"intentName" : "",
"intentValue" : ""
},
"messages" : {
"-KViVgc7ZG051eMXP0-5" : {
"name" : "Ed",
"text" : "Hello, I'm Ed, your personal assistant cum friend",
"timestamp" : "1476880306"
}
}
}
}
}


EDIT
OK, after debugging, I have discovered that the problem lies in these lines :
So, the problem is now narrowed down. Please help me find the rest of the error:

mFirebaseAdapter = new FirebaseRecyclerAdapter<FriendlyMessage,
MessageViewHolder>(
FriendlyMessage.class,
R.layout.item_message,
MessageViewHolder.class,
mFirebaseDatabaseReference.child(curFirebaseLocation)) {


@Override
protected void populateViewHolder(MessageViewHolder viewHolder,
FriendlyMessage friendlyMessage, int position) {
//...//
}





EDIT 2:
I noted an important aspect: While running the app without a data connection, the app still was showing the error "unfortunately Ed has stopped", this is not natural as earlier when my app was working(when my app was at one stage less than what it is today), it first used to load some data from the firebase database, then showed error. But this time, it shows the error even before it loads the data from the database, this leads to a conclusion that the error doesn't lie in the
snapshot
part of the problem, as if it would have had the case, the app wouldn't have shown the error in the offline state as until the data loads up, it should have been showing the progress dialog continuously.


EDIT 3 I found why am I getting the error:
This line :
mFirebaseAdapter = new FirebaseRecyclerAdapter(
FriendlyMessage.class,
R.layout.item_message,
MessageViewHolder.class,
mFirebaseDatabaseReference.child(curFirebaseLocation)) {...
In this line, when I pass some other string instead of
curFirebaseLocation
, there is no error and my app loads up fine but when I pass the
curFirebaseLocation
variable, I get the error as seen in the LogCat above. Now, I only need to know why am I getting the error
unable to convert java.lang.String to ...FriendlyMessage
, even when the value of both
curFirebaseLocation
and the string that I pass(upon which I get no error) is exactly the same. I think it has soething to do with the FirebaseRecyclerAdapter. Please help!!


NOTE: I logged the output of the
curFirebaseLocation
and
intentsMessage
Strings and found out that they were perfectly fine. When I copied them and pasted them in the browser, they led me to the exactly expected location.
Please mention if any more clarification is needed.
Thanks in advance!

Answer

Firebase needs an empty constructor in class. Make sure you explicitly defined an empty constructor in your FriendlyMessage class.

Comments