Sending friend-request using firebase on Android
<p>I'm migrating from Parse to Firebase. </p>

<p>My sendRequest function does the following tasks 
(Assume user1 sends request to user2)
-Check if the username exists
-Check if user1 has not already sent a request to user2
-Check if user1 and user2 are not already friends</p>

<p>Once these are done user2 receives a pushNotification and the respective fields are updated. </p>

<p>How would I do this on firebase considering the following structure? Would it have something to do with firebase-rules?</p>

<pre><code>Users    
   290384239843
      friends:
          093824098209384: true
      username: Bob 

Usernames
      Bob: 290384239843
      Jack: 5842258855552
      Carol: 093824098209384

PendingFriends
   290384239843 true
      list:
         093824098209384: pending
</code></pre>

<p><strong>Parse Cloud Code</strong></p>

<pre><code>Parse.Cloud.define("sendRequest",function(request, response) 
{
    // Username 1 = CurrentUser
    // Username 2 = FriendUser
    var username1 = request.params.username1;
    var username2 = request.params.username2;

    var user1 = request.params.user1;
    var p1 = Parse.User.createWithoutData(user1);

    var list = [];
    list[0]  = username1;
    list[1]  = username2;

    //NEW
    var realname1 = request.params.realname1;
    var usercolor1 = request.params.usercolor1;

    var query1 = new Parse.Query(Parse.User);
    query1.equalTo("username", username2);
    query1.first(
    {
        success: function(object1) 
        {
            //Yes "username2" exists

            if(object1 != null)
            {

                var user2 = object1.id;
                var p2 = object1;

                //NEW
                var realname2 = p2.get("realName");

                var query2 = new Parse.Query("PendingFriends");
                query2.containsAll("bothUsernames",list);
                query2.descending("createdAt");
                query2.first(
                {
                    success: function(object2) 
                    {
                        if(object2 != null)
                        {
                            var isDeleted   = object2.get("isDeleted");
                            var isAccepted  = object2.get("isAccepted");
                            var isUnfriend  = object2.get("isUnfriend");

                            if( (isDeleted==true) || (isAccepted==true &amp;&amp; isUnfriend==true) )
                            {
                                var FriendRequests = Parse.Object.extend("PendingFriends");
                                var fRequests      = new FriendRequests();

                                fRequests.set("usernameFrom", username1);
                                fRequests.set("userFrom", p1);
                                fRequests.set("usernameTo", username2);
                                fRequests.set("userTo", p2);
                                fRequests.set("bothUsernames",list);

                                //NEW
                                fRequests.set("realnameFrom",realname1);                                
                                fRequests.set("realnameTo", realname2);                             

                                fRequests.save(null, 
                                {
                                  success: function(fRequests) 
                                  {

                                    //----
                                    var pQuery = new Parse.Query(Parse.Installation);
                                    pQuery.equalTo('username', username2);

                                    Parse.Push.send(
                                    {
                                          where: pQuery,
                                          data: 
                                          {
                                            //alert: "You've got a friend request from " + realname1,
                                            request_message: "You've got a friend request from " + realname1,
                                            request_username: username1,
                                            request_realname: realname1,
                                            request_statuscolor: usercolor1,
                                            action: "com.app.REQUEST_RECEIVE"
                                          }
                                    },
                                    {
                                          success: function() 
                                          {
                                            // Push was successful
                                            response.success("Object 2 is NOT_NULL &amp; SAVED");   
                                          },
                                          error: function(pError) 
                                          {
                                            // Handle error
                                            response.error("Error(pError;O2!=Null): " + pError.code + " " + pError.message);
                                          }
                                    });
                                    //----

                                  },
                                  error: function(fRequests, errorSave) 
                                  {
                                    response.error("Error(errorSave;O2!=null): " + errorSave.code + " " + errorSave.message);
                                  }

                                });
                            }else
                            {
                                response.success("Object 2 is NOT_SAVING");
                            }

                        }else
                        {
                            var FriendRequests = Parse.Object.extend("PendingFriends");
                            var fRequests      = new FriendRequests();

                            fRequests.set("usernameFrom", username1);
                            fRequests.set("userFrom", p1);
                            fRequests.set("usernameTo", username2);
                            fRequests.set("userTo", p2);
                            fRequests.set("bothUsernames",list);

                            //NEW
                            fRequests.set("realnameFrom",realname1);                                
                            fRequests.set("realnameTo", realname2);                             

                            fRequests.save(null, 
                            {
                              success: function(fRequests) 
                              {

                                //----
                                var pQuery = new Parse.Query(Parse.Installation);
                                pQuery.equalTo('username', username2);

                                Parse.Push.send(
                                {
                                      where: pQuery,
                                      data: 
                                      {
                                        //alert: "You've got a friend request from " + username1,
                                        //action: "com.app.REFRESHREQUESTS"

                                        request_message: "You've got a friend request from " + realname1,
                                        request_username: username1,
                                        request_realname: realname1,
                                        request_statuscolor: usercolor1,
                                        action: "com.app.REQUEST_RECEIVE"
                                      }
                                },
                                {
                                      success: function() 
                                      {
                                        // Push was successful
                                        response.success("Object 2 is NULL &amp; SAVED");       
                                      },
                                      error: function(pError) 
                                      {
                                        // Handle error
                                        response.error("Error(pError;O2=Null): " + pError.code + " " + pError.message);
                                      }
                                });
                                //----

                              },
                              error: function(fRequests, errorSave) 
                              {
                                response.error("Error(errorSave;O2=Null): " + errorSave.code + " " + errorSave.message);
                              }

                            });
                        }
                    },
                    error: function(error2)
                    {
                        response.error("Error(error2): " + error2.code + " " + error2.message);
                    }
                });             
            }else
            {
                response.success("Object 1 is NULL");
            }

        },
        error: function(error1) 
        {
            response.error("error " + error1.message);
        }
    });
}); 
</code></pre>

<p><strong>Note:</strong>
I'm choosing to have PendingFriends as a separate tree as firebase downloads the all children nodes when you download the parent node. Which means everytime I download the user details, I would get a list of their friends &amp; pending-friends (which I have tried to avoid).</p>