Bonjour,
J'ai un problème dont je n'arrive pas à trouver la solution.

Voici un exemple pour illustrer mes propos:
J'ai plusieurs refuges (Shelter) pour animaux (Pet) : des chiens (Dog), des chats (Cat) et des hamsters (Hamster).
Je veux stocker ces refuges dans la base de données No SQL de Firebase.
J'aimerai ensuite voir une liste des refuges avec le nombre d'animaux qu'ils ont via le composant RecyclerView.

Le stockage fonctionne bien mais la récupération plante une erreur car ma classe abstraite Pet ne peut pas être instanciée (normal), comment je peux dire qu'il faut instancier les classes filles ?
Nom : Database.png
Affichages : 405
Taille : 10,8 Ko
Par contre sans la liste des animaux (petList) dans la base de donnée la récupération fonctionne :
Nom : Database2.png
Affichages : 364
Taille : 5,1 Ko
Nom : ScreenOk.png
Affichages : 372
Taille : 17,2 Ko

Techniquement j'ai :
=> 1 classe abstraite Pet
=> 3 classes filles Dog, Cat et Hamster.
=> 1 classe Shelter qui contient une liste d'animaux (Pet)

Classe abstraite Pet :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package com.example.gamo.testfirebase.models;
 
public abstract class Pet {
    public static final int DOG = 1;
    public static final int CAT = 2;
    public static final int HAMSTER = 3;
 
    private String name;
    private long weight;
    private int kind;
 
    public Pet(){
 
    }
 
    public Pet(int kind){
        this.kind = kind;
    }
 
    public abstract void cry();
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public long getWeight() {
        return weight;
    }
 
    public void setWeight(long weight) {
        this.weight = weight;
    }
 
    public int getKind() {
        return kind;
    }
 
    public void setKind(int kind) {
        this.kind = kind;
    }
}
Classe fille Dog:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
package com.example.gamo.testfirebase.models;
 
public class Dog extends Pet {
 
    public Dog() {
        super(Pet.DOG);
    }
 
    @Override
    public void cry() {
 
    }
}
Classe fille Cat:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
package com.example.gamo.testfirebase.models;
 
public class Cat extends Pet {
 
    public Cat() {
        super(Pet.CAT);
    }
 
    @Override
    public void cry() {
 
    }
}
Classe fille Hamster:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
package com.example.gamo.testfirebase.models;
 
public class Hamster extends Pet {
 
    public Hamster() {
        super(Pet.HAMSTER);
    }
 
    @Override
    public void cry() {
 
    }
}
Classe Shelter:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.example.gamo.testfirebase.models;
 
import java.util.ArrayList;
import java.util.List;
 
public class Shelter {
    private String key;
 
    private List<Pet> petList;
 
    public Shelter(){
        petList = new ArrayList<>();
    }
 
    public void add(Pet pet){
        petList.add(pet);
    }
 
    public String getKey() {
        return key;
    }
 
    public void setKey(String key) {
        this.key = key;
    }
 
    public List<Pet> getPetList() {
        return petList;
    }
 
    public void setPetList(List<Pet> petList) {
        this.petList = petList;
    }
}
Classe MainActivity:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package com.example.gamo.testfirebase;
 
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.support.v7.widget.RecyclerView;
import android.widget.ImageView;
import android.widget.TextView;
 
import com.example.gamo.testfirebase.models.Cat;
import com.example.gamo.testfirebase.models.Dog;
import com.example.gamo.testfirebase.models.Hamster;
import com.example.gamo.testfirebase.models.Shelter;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
 
public class MainActivity extends AppCompatActivity {
 
    Button create;
    private LinearLayoutManager mManager;
    private RecyclerView mRecycler;
    protected DatabaseReference databaseReference;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        create = findViewById(R.id.button);
 
        mRecycler = findViewById(R.id.messages_list);
        mRecycler.setHasFixedSize(true);
 
        mManager = new GridLayoutManager(this, 2);
        mRecycler.setLayoutManager(mManager);
        databaseReference = FirebaseDatabase.getInstance().getReference();
 
        firebaseTimerSearch();
 
        create.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Dog dog = new Dog();
                Cat cat = new Cat();
                Hamster hamster = new Hamster();
                Shelter shelter = new Shelter();
                shelter.add(dog);
                shelter.add(cat);
                shelter.add(hamster);
                shelter.setKey(databaseReference.child("test").push().getKey());
                databaseReference.child("test").child(shelter.getKey()).setValue(shelter);
            }
        });
    }
 
    private void firebaseTimerSearch(){
 
        Query firebaseSearchQuery = databaseReference.child("test");
 
        FirebaseRecyclerOptions options = new FirebaseRecyclerOptions.Builder<Shelter>()
                .setQuery(firebaseSearchQuery, Shelter.class)
                .build();
 
        if(mRecycler.getAdapter() instanceof FirebaseRecyclerAdapter){
            ((FirebaseRecyclerAdapter)mRecycler.getAdapter()).stopListening();
        }
        FirebaseRecyclerAdapter<Shelter, ShelterViewHolder> mAdapter = new FirebaseRecyclerAdapter<Shelter, ShelterViewHolder>(options) {
 
            @Override
            public ShelterViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
                LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());
                return new ShelterViewHolder(inflater.inflate(R.layout.shelter_element, viewGroup, false));
            }
 
            @Override
            protected void onBindViewHolder(ShelterViewHolder viewHolder, int position, final Shelter model) {
 
                viewHolder.bindToTimer(model);
            }
        };
 
        mAdapter.startListening();
        mRecycler.setAdapter(mAdapter);
    }
 
    public static class ShelterViewHolder extends RecyclerView.ViewHolder {
        TextView refTextView;
        TextView nbOfPetsTextView;
 
        public ShelterViewHolder(View itemView) {
            super(itemView);
 
            refTextView = itemView.findViewById(R.id.ref);
            nbOfPetsTextView = itemView.findViewById(R.id.nbOfPets);
        }
 
        public void bindToTimer(Shelter shelter) {
            refTextView.setText(shelter.getKey());
            nbOfPetsTextView.setText(String.valueOf(shelter.getPetList().size()));
        }
    }
}
Erreur lors de la récupération:
04-05 18:16:38.478 11285-11285/com.example.gamo.testfirebase E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.gamo.testfirebase, PID: 11285
java.lang.RuntimeException: java.lang.InstantiationException: Can't instantiate abstract class com.example.gamo.testfirebase.models.Pet
at com.google.android.gms.internal.zzeph.zze(Unknown Source:307)
at com.google.android.gms.internal.zzepg.zzb(Unknown Source:198)
at com.google.android.gms.internal.zzepg.zza(Unknown Source:303)
at com.google.android.gms.internal.zzepg.zza(Unknown Source:60)
at com.google.android.gms.internal.zzepg.zzb(Unknown Source:0)
at com.google.android.gms.internal.zzeph.zze(Unknown Source:126)
at com.google.android.gms.internal.zzepg.zzb(Unknown Source:198)
at com.google.android.gms.internal.zzepg.zza(Unknown Source:0)
at com.google.firebase.database.DataSnapshot.getValue(Unknown Source:10)
at com.firebase.ui.database.ClassSnapshotParser.parseSnapshot(ClassSnapshotParser.java:29)
at com.firebase.ui.database.ClassSnapshotParser.parseSnapshot(ClassSnapshotParser.java:15)
at com.firebase.ui.common.BaseCachingSnapshotParser.parseSnapshot(BaseCachingSnapshotParser.java:35)
at com.firebase.ui.common.BaseObservableSnapshotArray.get(BaseObservableSnapshotArray.java:52)
at com.firebase.ui.database.FirebaseRecyclerAdapter.getItem(FirebaseRecyclerAdapter.java:106)
at com.firebase.ui.database.FirebaseRecyclerAdapter.onBindViewHolder(FirebaseRecyclerAdapter.java:122)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6508)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6541)
at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5484)
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5750)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5589)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5585)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2231)
at android.support.v7.widget.GridLayoutManager.layoutChunk(GridLayoutManager.java:556)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1518)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:610)
at android.support.v7.widget.GridLayoutManager.onLayoutChildren(GridLayoutManager.java:170)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3719)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3436)
at android.support.v7.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:1742)
at android.support.v7.widget.RecyclerView$1.run(RecyclerView.java:354)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
at android.view.Choreographer.doCallbacks(Choreographer.java:723)
at android.view.Choreographer.doFrame(Choreographer.java:655)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Caused by: java.lang.InstantiationException: Can't instantiate abstract class com.example.gamo.testfirebase.models.Pet
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:334)
at com.google.android.gms.internal.zzeph.zze(Unknown Source:54)
at com.google.android.gms.internal.zzepg.zzb(Unknown Source:198)*
at com.google.android.gms.internal.zzepg.zza(Unknown Source:303)*
at com.google.android.gms.internal.zzepg.zza(Unknown Source:60)*
at com.google.android.gms.internal.zzepg.zzb(Unknown Source:0)*
at com.google.android.gms.internal.zzeph.zze(Unknown Source:126)*
at com.google.android.gms.internal.zzepg.zzb(Unknown Source:198)*
at com.google.android.gms.internal.zzepg.zza(Unknown Source:0)*
at com.google.firebase.database.DataSnapshot.getValue(Unknown Source:10)*
at com.firebase.ui.database.ClassSnapshotParser.parseSnapshot(ClassSnapshotParser.java:29)*
at com.firebase.ui.database.ClassSnapshotParser.parseSnapshot(ClassSnapshotParser.java:15)*
at com.firebase.ui.common.BaseCachingSnapshotParser.parseSnapshot(BaseCachingSnapshotParser.java:35)*
at com.firebase.ui.common.BaseObservableSnapshotArray.get(BaseObservableSnapshotArray.java:52)*
at com.firebase.ui.database.FirebaseRecyclerAdapter.getItem(FirebaseRecyclerAdapter.java:106)*
at com.firebase.ui.database.FirebaseRecyclerAdapter.onBindViewHolder(FirebaseRecyclerAdapter.java:122)*
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6508)*
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6541)*
at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5484)*
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5750)*
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5589)*
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5585)*
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2231)*
at android.support.v7.widget.GridLayoutManager.layoutChunk(GridLayoutManager.java:556)*
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1518)*
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:610)*
at android.support.v7.widget.GridLayoutManager.onLayoutChildren(GridLayoutManager.java:170)*
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3719)*
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3436)*
at android.support.v7.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:1742)*
at android.support.v7.widget.RecyclerView$1.run(RecyclerView.java:354)*
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)*
at android.view.Choreographer.doCallbacks(Choreographer.java:723)*
at android.view.Choreographer.doFrame(Choreographer.java:655)*
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)*
at android.os.Handler.handleCallback(Handler.java:790)*
at android.os.Handler.dispatchMessage(Handler.java:99)*
at android.os.Looper.loop(Looper.java:164)*
at android.app.ActivityThread.main(ActivityThread.java:6494)*
at java.lang.reflect.Method.invoke(Native Method)*
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)*
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)*