🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

解決済

1回答

1199閲覧

Firebase上のデータベースの一部をテキストとしてアプリ画面に表示したい

nemo3002

総合スコア3

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

0グッド

0クリップ

投稿2020/12/27 11:29

編集2020/12/27 11:31

前提・実現したいこと

firebaseのRealtime Databaseを用いて掲示板のような機能を持つandroidアプリを作っています。下図で示したようなfirebase上のdatabaseからpeople部分をアプリ上にテキストとして表示したいのですがよくわからないエラーが起きてしまいました。解決方法を教えてくださいませんか?よろしくお願いします。

イメージ説明

発生している問題・エラーメッセージ

com.google.firebase.database.DatabaseException: Expected a List while deserializing, but got a class java.util.HashMap

該当のソースコード

java

1package com.example.cyberuniversity; 2 3import android.content.Intent; 4import android.os.Bundle; 5import android.view.View; 6import android.widget.EditText; 7import android.widget.TextView; 8import android.widget.Toast; 9 10import androidx.annotation.NonNull; 11import androidx.appcompat.app.AppCompatActivity; 12 13import com.google.firebase.auth.FirebaseAuth; 14import com.google.firebase.auth.FirebaseUser; 15import com.google.firebase.database.DataSnapshot; 16import com.google.firebase.database.DatabaseError; 17import com.google.firebase.database.DatabaseReference; 18import com.google.firebase.database.FirebaseDatabase; 19import com.google.firebase.database.GenericTypeIndicator; 20import com.google.firebase.database.ValueEventListener; 21 22import java.util.List; 23 24public class DatabaseActivity extends AppCompatActivity { 25 private TextView textView1; 26 private FirebaseAuth mAuth; 27 private FirebaseDatabase database; 28 private EditText mesText; 29 private EditText dataText; 30 @Override 31 public void onCreate (Bundle savedInstanceState) { 32 super.onCreate(savedInstanceState); 33 setContentView(R.layout.activity_database); 34 mAuth = FirebaseAuth.getInstance(); 35 database = FirebaseDatabase.getInstance(); 36 FirebaseUser currentUser = mAuth.getCurrentUser(); 37 updateUI(currentUser); 38 //↑activity開いてすぐやる  39 // ↓xmlから取得 40 mesText = findViewById(R.id.messageText); 41 dataText = findViewById(R.id.recieveData); 42 43 DatabaseReference people = database.getReference("people"); 44 45 people.addValueEventListener(new ValueEventListener() { 46 @Override 47 public void onDataChange(DataSnapshot snapshot) { 48 GenericTypeIndicator<List<Person>> gt_indicator = 49 new GenericTypeIndicator<List<Person>>() {}; 50 List<Person> values = snapshot.getValue(gt_indicator); 51 String res = ""; 52 for (Object p: values){ 53 res += p + "\n"; 54 } 55 dataText.setText(res); 56 } 57 58 @Override 59 public void onCancelled(@NonNull DatabaseError error) { 60 61 } 62 }); 63 } 64 65 public void doLogout(View view) { 66 mAuth.signOut(); 67 Toast.makeText(DatabaseActivity.this, "Logouted...", Toast.LENGTH_LONG).show(); 68 Intent intent = new Intent(DatabaseActivity.this, MainActivity.class); 69 startActivity(intent); 70 } 71 72 public void updateUI (FirebaseUser user) { 73 textView1 = findViewById(R.id.textView); 74 if (user == null) { 75 textView1.setText("no login..."); 76 } else { 77 textView1.setText("login: " + user.getEmail()); 78 } 79 } 80 81 public void doAction(View view) { 82 DatabaseReference myRef = database.getReference("message"); 83 String s = mesText.getText() + ""; 84 myRef.setValue(s); 85 Toast.makeText(DatabaseActivity.this, "write data!", 86 Toast.LENGTH_SHORT).show(); 87 } 88 89 class Person { 90 public int age; 91 public String mail; 92 public String name; 93 public String university; 94 95 96 97 public Person(){}; 98 99 100 public Person(int age, String mail, String name, String university){ 101 this.age = age; 102 this.mail = mail; 103 this.name = name; 104 this.university = university; 105 } 106 107 108 public String toString(){ 109 return this.name + " [" + this.mail + "," + this.age + "," + this.university + "]"; 110 } 111 } 112 113} 114

試したこと

補足情報(FW/ツールのバージョンなど)

android studio 4.1.1を用いています。
サーバーレス開発プラットフォームFIREBASE入門という書籍を参考にしています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

動かしてみていませんが、多分

GenericTypeIndicator<List<Person>> gt_indicator = new GenericTypeIndicator<List<Person>>() {}; List<Person> values = snapshot.getValue(gt_indicator);

でエラーが出てます。

このsnapshotの値をリスト型で受けるとすると、people/{personID}の全部を取得できるとして、このpersonIDはどこに消えてしまうのでしょう。

personIDは欠番のない連番でも、ましてや数値でもありませんので、上記のコードで取得できてしまうとリストに入っているPersonが一体どのIDに属するのかわかりません。

なので、snapshotは値としては、Map<String,Object>あたりを持っていると思います。

上記は私の仮説ですが、その通りかどうかを確かめて見てはいかがでしょう。

開発時には、DBなど外部のシステムと連携させる部分では、型として何が返ってきているのか、ゆっくりと確認しながらやっていくとよいと思います。

たとえば、

Object object = snapshot.getValue(); Log.d("firestore",object.getClass().toString())

として、ライブラリが任意の型として判定しているときの型をチェックしてみる。

それがMap型だった際には、KeyやValueの型を確かめる。

ValueやKeyを自分で作成した型に自動的に変換する仕組みが思ったとおりに動くのかを確かめる。

と、順序を整理してやっていくと不安だったり分からない部分を払拭しながらものづくりを勧めていけると思います。

投稿2020/12/28 08:19

編集2020/12/28 08:49
aya-eiya

総合スコア97

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nemo3002

2020/12/28 15:21

問題解決しました!realtime databaseからのデータの取得において、「取り出す値はJSONオブジェクトで表現できる任意の型だから、利用者が適宜適切な型にキャストして利用しなければならない。」ということを理解していませんでした。 aya-eiyaさんにご指摘いただいたことと、 https://gihyo.jp/dev/serial/01/firebase/0003? こちらのサイトを読み込むことで理解が大変深まりました。 さらにlogの使い方、HashMapの意味など様々なことを勉強させていただきました。本当にありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問