48 votes

Comment retourner la valeur de DataSnapshot comme résultat d'une méthode ?

Je n'ai pas beaucoup d'expérience avec Java. Je ne sais pas si cette question est stupide, mais j'ai besoin d'obtenir un nom d'utilisateur à partir de la base de données en temps réel Firebase et de retourner ce nom comme résultat de cette méthode. J'ai donc trouvé comment obtenir cette valeur, mais je ne comprends pas comment la renvoyer comme résultat de cette méthode. Quelle est la meilleure façon de procéder ?

private String getUserName(String uid) {
    databaseReference.child(String.format("users/%s/name", uid))
            .addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            // How to return this value?
            dataSnapshot.getValue(String.class);
        }

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

1 votes

Comme @PeterHaddad l'a mentionné, la méthode onDataChange est asynchrone, ce qui signifie qu'elle renverra toujours null. Puis-je demander : pourquoi avez-vous besoin de retourner le nom de l'utilisateur ? Pourquoi ne pas simplement utiliser ce nom dans la méthode onDataChange ?

2 votes

Comme l'a dit @PeterHaddad, parce que onDataChange() est appelée asynchrone, cela ne fonctionnera pas. Veuillez consulter ma réponse.

1 votes

Lisez ceci pour comprendre pourquoi les API de Firebase sont asynchrones : medium.com/@CodingDoug/

0voto

DragonFire Points 496

Il ne s'agit PAS d'une solution, mais simplement d'un moyen d'accéder aux données en dehors de la méthode pour l'organisation du code.

// Get Your Value
private void getValue() {

    fbDbRefRoot.child("fbValue").addListenerForSingleValueEvent(new ValueEventListener() {

        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

            String yourValue = (String) dataSnapshot.getValue();
            useValue(yourValue);

        }

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

        }
    });

}

// Use Your Value
private void useValue(String yourValue) {

    Log.d(TAG, "countryNameCode: " + yourValue);

}

Une autre façon d'atteindre un résultat (mais pas nécessairement une solution)

Déclarer une variable publique

public static String aPublicVariable;

Définir cette variable dans la méthode asynchrone

aPublicVariable = (String) dataSnapshot.getValue();

Utilisez la variable n'importe où

Log.d(TAG, "Not Elegant: " + aPublicVariable);

Dans la deuxième méthode, si l'appel asynchrone n'est pas long, il fonctionnera presque tout le temps.

0 votes

J'ai essayé quelque chose de similaire, la valeur est passée avant même que les données soient récupérées et finit par être nulle.

0 votes

Cela va continuer à se mettre à jour 1000 fois, je travaille avec un portefeuille qui implique de l'argent. Lorsque je mets à jour en ajoutant le nouveau montant au montant actuel dans la base de données. Il continue de répéter le processus et d'augmenter l'argent jusqu'à ce que vous quittiez l'application parce que c'est une méthode asynchrone donc c'est dangereux de travailler avec des nombres. Je pense que pour les chaînes de caractères, vous ne verrez pas les effets.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X