Search code examples
javaandroidfirebasefirebase-realtime-databasetoken

Can't convert object of type java.lang.String to type, when I want to FCM send notifitcation


Can't convert an object of type java.lang.String to type, when I want to FCM send notifications.

In my TokenModel

public class TokenModel {
  private String token;

  public TokenModel(String token) {
    this.token = token;
  }

  public TokenModel() {}

  public String getToken() {
    return token;
  }

  public void setToken(String token) {
    this.token = token;
  }
}

And SendNotification.java

private void sendNotification(String receiver, String username, String msg) {
  DatabaseReference tokens = FirebaseDatabase.getInstance().getReference("Tokens");
  Query query = tokens.orderByKey().equalTo(receiver);
  query.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
      for (DataSnapshot snapshot: dataSnapshot.getChildren()) {
        TokenModel tokenModel = snapshot.getValue(TokenModel.class);
        MessageTokenDataModel data = new MessageTokenDataModel(firebaseUser.getUid(), R.mipmap.ic_launcher, username + ": " + msg, "New Message", userid);

        Sender sender1 = new Sender(data, tokenModel.getToken());

        apiService.sendNotification(sender1)
          .enqueue(new Callback<MyResponse>() {
            @Override
            public void onResponse(Call<MyResponse> call, Response<MyResponse> response) {
              if (response.code() == 200) {
                if (response.body().success != 1) {
                  Toast.makeText(NewChatActivity.this, "Failed", Toast.LENGTH_SHORT).show();
                }
              }
            }

            @Override
            public void onFailure(Call<MyResponse> call, Throwable t) {

            }
          });
      }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError error) {

    }
  });
}

But in this line, I will get the error:

TokenModel tokenModel = snapshot.getValue(TokenModel.class);

The under data is my firebase data

enter image description here


Solution

  • You are getting the following error:

    Can't convert an object of type java.lang.String to type TokenModel

    Because when you are using the following reference:

    DatabaseReference tokens = FirebaseDatabase.getInstance().getReference("Tokens");
    

    And you loop through the results using a call to .getChildren() method, it means that you want to get all children that exist under that reference. When using the following line of code:

    TokenModel tokenModel = snapshot.getValue(TokenModel.class);
    

    It means that you are trying to convert each child into an object of type TokenModel, which is not possible since each child is a String and not a TokenModel, hence that error.

    To solve this, you should store under the "Tokens" node, Token objects. So your schema should look like this:

    Firebase-root
      |
      --- Tokens
            |
            --- $tokenId
            |     |
            |     --- token: "f5VI ... 2zjR..."
            |
            --- $tokenId
                  |
                  --- token: "c8H7 ... 9pMC..."
    

    If you change the schema as above, in code there is nothing you should do. It should work as expected.