Problems getting data on Android with Firebase

I just learned how to set up Firebase data on Android. I can write a db, but I cannot read and display it in my application. My application is very simple (it only has one main screen at the moment) and I don't care how the data is displayed on the page as I'm just learning - I'm currently trying to display it as text.

Here is my main java activity:

package com.example.ispotrachel.myapplication;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;

import com.firebase.client.DataSnapshot;
import com.firebase.client.Firebase;
import com.firebase.client.FirebaseError;
import com.firebase.client.ValueEventListener;

import java.util.HashMap;
import java.util.Map;


public class MainActivity extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Firebase.setAndroidContext(this);

    Firebase ref = new Firebase("https://blistering-torch-9015.firebaseio.com");

    class User {
        private int birthYear;
        private String fullName;

        public User() {
        }

        public User(String fullName, int birthYear) {
            this.fullName = fullName;
            this.birthYear = birthYear;
        }

        public long getBirthYear() {
            return birthYear;
        }

        public String getFullName() {
            return fullName;
        }
    }

     User user1 = new User("Name 1", 1982);
     User user2 = new User("Name 2", 1972);

     Firebase usersRef = ref.child("users");

     Map<String, User> users = new HashMap<String, User>();
     users.put("user1", user1);
     users.put("user 2", user2);

    usersRef.setValue(users);

    Firebase postRef = ref.child("posts");

    Map<String, String> post1 = new HashMap<String, String>();
    post1.put("author", "user1");
    post1.put("title", "Announcing COBOL, a New Programming Language");
    postRef.push().setValue(post1);

    Map<String, String> post2 = new HashMap<String, String>();
    post2.put("author", "user2");
    post2.put("title", "The Turing Machine");
    postRef.push().setValue(post2);
    ref.addValueEventListener(new ValueEventListener() {


    @Override
    public void onDataChange(DataSnapshot arg0) {
            //System.out.println(arg0.getValue());
            TextView textViewSample = (TextView) findViewById(R.id.sampleTextView);
            textViewSample.setText(arg0.getValue(String.class));
        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {
            System.out.println("the read failed");
        }

    });
}}

      

Here is my activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
 android:layout_height="match_parent"           android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">


<TextView
    android:id="@+id/sampleTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hello_world"/>


</LinearLayout>

      

When I run the application, it crashes. Here is the logcat error message:

12-27 12:15:02.678    1895-1895/com.example.ispotrachel.myapplication I/art﹕ Not late     enabling -Xcheck:jni (already on)
12-27 12:15:02.946    1895-1907/com.example.ispotrachel.myapplication I/art﹕ Background     sticky concurrent mark sweep GC freed 3867(286KB) AllocSpace objects, 0(0B) LOS objects, 11% free, 1009KB/1135KB, paused 2.595ms total 117.910ms
12-27 12:15:03.317    1895-1926/com.example.ispotrachel.myapplication D/OpenGLRenderer﹕ Render dirty regions requested: true
12-27 12:15:03.320    1895-1895/com.example.ispotrachel.myapplication D/﹕ HostConnection::get() New Host Connection established 0xa6667e80, tid 1895
12-27 12:15:03.327    1895-1895/com.example.ispotrachel.myapplication D/Atlas﹕ Validating map...
12-27 12:15:03.391    1895-1926/com.example.ispotrachel.myapplication D/﹕ HostConnection::get() New Host Connection established 0xa66ef3b0, tid 1926
12-27 12:15:03.405    1895-1926/com.example.ispotrachel.myapplication I/OpenGLRenderer﹕ Initialized EGL, version 1.4
12-27 12:15:03.422    1895-1926/com.example.ispotrachel.myapplication D/OpenGLRenderer﹕ Enabling debug mode 0
12-27 12:15:03.439    1895-1926/com.example.ispotrachel.myapplication W/EGL_emulation﹕ eglSurfaceAttrib not implemented
12-27 12:15:03.439    1895-1926/com.example.ispotrachel.myapplication W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xa66b7880, error=EGL_SUCCESS
12-27 12:15:07.474    1895-1926/com.example.ispotrachel.myapplication W/EGL_emulation﹕ eglSurfaceAttrib not implemented
12-27 12:15:07.474    1895-1926/com.example.ispotrachel.myapplication W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xa66b7880, error=EGL_SUCCESS
12-27 12:15:13.993    1895-1895/com.example.ispotrachel.myapplication D/AndroidRuntime﹕    Shutting down VM 

--------- beginning of crash
12-27 12:15:13.993    1895-1895/com.example.ispotrachel.myapplication E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.ispotrachel.myapplication, PID: 1895 com.firebase.client.FirebaseException: Failed to bounce to type 
        at com.firebase.client.DataSnapshot.getValue(DataSnapshot.java:196)
        at com.example.ispotrachel.myapplication.MainActivity$1.onDataChange(MainActivity.java:79) 
        at com.firebase.client.core.ValueEventRegistration$1.run(ValueEventRegistration.java:48)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5221)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

 Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token
        at [Source: java.io.StringReader@c8f7297; line: 1, column: 1]
        at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:575)
        at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:46)
        at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:11)
        at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888)
        at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2034)
        at com.firebase.client.DataSnapshot.getValue(DataSnapshot.java:192)
        at com.example.ispotrachel.myapplication.MainActivity$1.onDataChange(MainActivity.java:79)
        at com.firebase.client.core.ValueEventRegistration$1.run(ValueEventRegistration.java:48)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5221)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)device not found

      

+3


source to share


2 answers


TL; DR

It looks like you are trying to load a JSON object into a string.

The error message Failed to bounce to type

indicates that the Firebase client has returned some data, but cannot convert it to the type you specified.

Problem Details

You add ValueEventListener

to the root of your Firebase here:

ref.addValueEventListener(new ValueEventListener() { ...

      



In this value event listener, you are telling Firebase to load the whole Firebase as String

:

textViewSample.setText(arg0.getValue(String.class));

      

And it would work if you had a very simple Firebase containing only one line. However, based on the rest of your code, it looks like your Firebase has a lot more String

in it :)

How to fix it You have several options:

  • Attach an event listener further down the tree. You can get the user's full name as a string:

    ref.child("users/user1/fullName").addValueEventListener(new ValueEventListener() {
    
        @Override
        public void onDataChange(DataSnapshot arg0) {
            TextView textViewSample = (TextView) findViewById(R.id.sampleTextView);
            textViewSample.setText(arg0.getValue(String.class));
        }
        ...
    }
    
          

  • Or you can get the whole user, but parse it like User

    instead String

    :

    ref.child("users/user1/fullName").addValueEventListener(new ValueEventListener() {
    
        @Override
        public void onDataChange(DataSnapshot arg0) {
            User tempUser = arg0.getValue(User.class);
            TextView textViewSample = (TextView) findViewById(R.id.sampleTextView);
            textViewSample.setText(tempUser.getFullName());
        }
        ...
    }
    
          

+2


source


I have a similar problem.

This is the code from which I am fetching data from firebase:

    DatabaseReference chatRef = database.getReference("chats");
    chatRef.keepSynced(true);
    Query queryRef = chatRef.orderByChild("id");

    queryRef.addChildEventListener(new ChildEventListener() {
        // Retrieve new posts as they are added to the database
        @Override
        public void onChildAdded(DataSnapshot snapshot, String previousChildKey) {
            ChatPost newPost = snapshot.getValue(ChatPost.class);
            ChatPost topic = new ChatPost(newPost.id, newPost.topic);
            addChatTopic(topic);
            System.out.println("NEW Child Topic: " + newPost.topic);

            chatAdapter.addItem(newPost);
        }

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {
            ChatPost newPost = dataSnapshot.getValue(ChatPost.class);
            ChatPost topic = new ChatPost(newPost.id, newPost.topic);
            addChatTopic(topic);
            System.out.println("CHANGED Child Topic: " + newPost.topic);

            chatAdapter.updateItem(newPost);
        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {
            ChatPost newPost = dataSnapshot.getValue(ChatPost.class);
            ChatPost topic = new ChatPost(newPost.id, newPost.topic);
            chatTopicsList.add(topic);
            System.out.println("REMOVED Child Topic: " + newPost.topic);

            chatAdapter.removeItem(newPost);
        }

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

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

      

It worked until I used push () to add a new item. My data in firebase console looks like here .

Exception text:

07-05 16: 45: 07.097 29997-29997 / com.skl.bingofire E / AndroidRuntime: FATAL EXCEPTION: Main Process: com.skl.bingofire, PID: 29997 com.google.firebase.database.DatabaseException: List expected during deserialization, but got the java.util.HashMap class at com.google.android.gms.internal.zzaix.zza (Unknown source) at com.google.android.gms.internal.zzaix.zza (Unknown source) at com.google .android.gms.internal.zzaix.zzb (Unknown source) at com.google.android.gms.internal.zzaix $ zza.zze (Unknown source) at com.google.android.gms.internal.zzaix $ zza.zzaC (Unknown source) at com.google. android.gms.internal.zzaix.zzd (Unknown source) at com.google.android.gms.internal.zzaix.zzb (Unknown source) at com.google.android.gms.internal.zzaix.zza (Unknown source) at com.google.firebase.database.DataSnapshot.getValue (Unknown source) at com.skl.bingofire.activities.MainActivity $ 7.onChildAdded (MainActivity.java:228) at com.google.android.gms.internal.zzaer.zza (Unknown source) at com.google.android. gms.internal.zzagp.zzSu (Unknown source) at com.google.android.gms.internal.zzags $ 1.run (Unknown source) on android.os.Handler.handleCallback (Handler.java:739) on android.os. Handler.dispatchMessage (Handler.java:95) at android.os.Looper.loop (Looper.java:148) at android.app.ActivityThread.main (ActivityThread.java:5417) at java.lang.reflect.Method.invoke (native method) at com.android .internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:616) 07-05 16: 45: 16.924 29997-30029 / com. skl.bingofire E / DynamiteModule: Failed load module descriptor class: Could not find class' Com.google.android.gms.dynamite.descriptors.com.google.firebase.auth.ModuleDescriptor "along the path: DexPathList [[zip file" /data/app/com.skl.bingofire-1/base.apk "], nativeLibraryDirectories = [/ data / app / com.skl.bingofire-1 / lib / arm, / vendor / lib, / system / lib]]



I used this model:

class ChatPost {
    public String id;
    public String topic;
    public String color;
    public ArrayList<Message> messages;
}

      

I figured out that if the data list contains a key like "-KLdskjdkjkjdjksjdksjdjsdjsjk", firebase will recognize the hole list as "HashMap" otherwise as "ArrayList". I changed my model to this structure:

class ChatPost {
    public String id;
    public String topic;
    public String color;
    public HashMap<String, Message> messages;
}

      

And I added a chat with a key like "-KLdskjdkjkjdjksjdksjdjsdjsjk" to the rest of the messages. And my code is working now. But I think this is not obvious.

0


source







All Articles