0

I have a user class, which have a contactlist(friends). I want to add the possibility to add friends.

My database database

In my code I have a addFriend method, which call a checkUser method. Here I check if the user exists so I can add him in the friend list. I am having difficulties implementing that, like how can I retrieve a variable from an anonymous class?

Here is my code.

package com.android.pfe.other;

import android.support.annotation.Keep;
import android.util.Log;

import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.IgnoreExtraProperties;
import com.google.firebase.database.Query;
import com.google.firebase.database.ValueEventListener;

import java.io.Serializable;
import java.util.Hashtable;
import java.util.List;

/**
 * Created by SADA INFO on 13/04/2018.
 */
@IgnoreExtraProperties
@Keep
public class User implements Serializable {
    private static final String TAG ="UserClass" ;
    public String username;
    public String email;
    public Hashtable contact;
    public String Uid;
    public List article;
    public DatabaseReference mDatabase;
    public List<User> UserList;
    public User uti;
    public User() {
        // Default constructor required for calls to DataSnapshot.getValue(com.android.pfe.other.User.class)
    }

    public User(String username, String email,String uid) {
        this.username = username;
        this.email = email;
        this.contact=new Hashtable<String,Boolean>();
        this.Uid=Uid;


    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public void addUser(String UserId, String name, String email) {
        mDatabase = FirebaseDatabase.getInstance().getReference("User");
        User user = new User(name, email,UserId);
        mDatabase.child(UserId).setValue(user);

    }
    public void addFriend(String UserId, final String email)
    {
        mDatabase = FirebaseDatabase.getInstance().getReference("User");
        DatabaseReference user = mDatabase.child(UserId);
        final DatabaseReference friendlist = user.child("contact");

        if(checkUser(email)==true)
        friendlist.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                Hashtable list = dataSnapshot.getValue(Hashtable.class);
                if(list.isEmpty())
                {
                    friendlist.setValue(email);
                }

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });

    }
    public boolean checkUser(String email){
        Query query = FirebaseDatabase.getInstance().getReference("User").orderByChild("email").equalTo(email);
        query.addListenerForSingleValueEvent(mValueEventListener);
       if(uti==null)
       {
           return false;
       }
        return true;
    }

    ValueEventListener mValueEventListener=new ValueEventListener() {

        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
        if(dataSnapshot.exists())
        {
            uti=dataSnapshot.getValue(User.class);

        }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.w(TAG, "loadUser:onCancelled", databaseError.toException());
        }
    };

} 
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Anis Kaloun
  • 171
  • 1
  • 14
  • You can provide the realm database :https://realm.io/docs/java/latest/ – propoLis Apr 19 '18 at 13:02
  • 1
    The user data is loaded for Firebase asynchronously. By the time your `if(uti==null)` runs, the data won't be loaded yet, so it will always be `null`. For some good answers on this topic, see: https://stackoverflow.com/a/47853774, https://stackoverflow.com/a/33204705, https://stackoverflow.com/a/40099900, https://stackoverflow.com/a/31702957, Doug's [blog post](https://medium.com/google-developers/why-are-firebase-apis-asynchronous-callbacks-promises-tasks-e037a6654a93) and new [video series](https://youtu.be/7IkUgCLr5oA). – Frank van Puffelen Apr 19 '18 at 13:16

1 Answers1

1

I would recommend that you define an interface say 'ICheckUserListener' with something like onSuccess(DataSnapshot dataSnapshot) and onError(Exception e) methods.

public void checkUser(String email, ICheckUserListener listener) 
//Since this method is independent of a specific User instance, it can be static which would require minor adjustments to prevent a memory-leak
{
    ValueEventListener mValueEventListener = new ValueEventListener() 
    {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) 
        {
            listener.success(dataSnapshot.exists() ? dataSnapshot : null);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) 
        {
            Log.w(TAG, "loadUser:onCancelled", databaseError.toException());
            listener.onError(databaseError.toException());
        }
    };

    FirebaseDatabase
       .getInstance()
       .getReference("User")
       .orderByChild("email") //This is redundant if email ids are unique
       .equalTo(email)
       .addListenerForSingleValueEvent(mValueEventListener);

}

You can then implement 'ICheckUserListener' in your 'addFriend' method to handle the result.

Karan Modi
  • 972
  • 2
  • 13
  • 26