11

I am working on a project where user request for our valet services and on the other end valet accepts request.

I am using using Firebase as backend and on request customer uid is save on 'request' child.

When valet accepts request, customer uid should move from 'request' node to 'on progress' node.

How can i do that?

adjuremods
  • 2,938
  • 2
  • 12
  • 17
Shakeel Dhada
  • 113
  • 1
  • 1
  • 6

4 Answers4

10

I recommend using this :

public void moveFirebaseRecord(Firebase fromPath, final Firebase toPath)
{
    fromPath.addListenerForSingleValueEvent(new ValueEventListener()
    {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot)
        {
            toPath.setValue(dataSnapshot.getValue(), new Firebase.CompletionListener()
            {
                @Override
                public void onComplete(FirebaseError firebaseError, Firebase firebase)
                {
                    if (firebaseError != null)
                    {
                        System.out.println("Copy failed");
                    }
                    else
                    {
                        System.out.println("Success");
                    }
                }
            });
        }

        @Override
        public void onCancelled(FirebaseError firebaseError)
        {
            System.out.println("Copy failed");
        }
    });
}

This come from this source : https://gist.github.com/katowulf/6099042 . I used it several times in my JavaEE code and also in my android app.

You pass your fromPath and toPath. This is a copy tought and not a move, so the original will remain at his original place too. If you would like to delete, you can do a set value on the fromPath just after the System.out.println("Success"); .

Ali Haidar
  • 116
  • 1
  • 5
  • It works fine but it uses firebase url as path(ref) and moves all child. I want to move only one child with is selected. How to move only one child. TIA – Shakeel Dhada Nov 07 '16 at 12:49
  • If you have the ID of your child, then you can move from one ID directly to the other one. – Ali Haidar Nov 07 '16 at 16:11
  • It would like : myfirebase.firebase.com/initialPlace/ID to myfirebase.firebase.com/finalPlace/ID . You can pass any string as a variable to the firebase constructor. – Ali Haidar Nov 07 '16 at 16:13
9

As of compile firebase-database:11.0.1, this is the same function with the new class references (https://firebase.google.com/support/guides/firebase-android July 05 2017)

private void moveGameRoom(final DatabaseReference fromPath, final DatabaseReference toPath) {
        fromPath.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                toPath.setValue(dataSnapshot.getValue(), new DatabaseReference.CompletionListener() {
                    @Override
                    public void onComplete(DatabaseError firebaseError, DatabaseReference firebase) {
                        if (firebaseError != null) {
                            System.out.println("Copy failed");
                        } else {
                            System.out.println("Success");

                        }
                    }
                });

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
    }
Mathoa
  • 143
  • 1
  • 6
3

If you want to perform a move which also erases the original, you might make use of the following snippet:

// In this piece of code, "fromPath" and "toPath" parameters act like directories.
private void removeFromFirebase(final DatabaseReference fromPath, final DatabaseReference toPath, final String key) {
    fromPath.child(key).addListenerForSingleValueEvent(new ValueEventListener() {
        // Now "DataSnapshot" holds the key and the value at the "fromPath".
        // Let's move it to the "toPath". This operation duplicates the
        // key/value pair at the "fromPath" to the "toPath".
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            toPath.child(dataSnapshot.getKey())
                    .setValue(dataSnapshot.getValue(), new DatabaseReference.CompletionListener() {
                        @Override
                        public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
                            if (databaseError == null) {
                                Log.i(TAG, "onComplete: success");
                                // In order to complete the move, we are going to erase
                                // the original copy by assigning null as its value.
                                fromPath.child(key).setValue(null);
                            }
                            else {
                                Log.e(TAG, "onComplete: failure:" + databaseError.getMessage() + ": "
                                        + databaseError.getDetails());
                            }
                        }
                    });
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.e(TAG, "onCancelled: " + databaseError.getMessage() + ": "
                    + databaseError.getDetails());
        }
    });
}
felixy
  • 179
  • 1
  • 6
  • What is the value of key? – LizG Aug 18 '18 at 05:43
  • In a javascript object the "key" would be any property name associated with a non-null value. The "fromPath" would be the object branch leading to that key, and the "toPath" would be the object branch that will lead to that key. For example: `{ user1: { name: 'Jack', address: { line1: 'some st', } } }` If here what you'd like to move would be the address, the key would be "address", the fromPath would be "/user1/" and the toPath would be "/junkAddress/user1/" The key could also be a push key. – felixy Aug 18 '18 at 07:27
  • how do I get the value of "key" so that when I delete the contents. Basically when I call the method removeFromFirebase(fromPath, toPath, key) how do I get the value of key? – LizG Aug 19 '18 at 04:29
  • You only need to do `toPath.child(key).addListenerForSingleValueEvent(/***/);` to retrieve the same value from the new path. – felixy Aug 19 '18 at 12:41
  • In this case the same code might be run multiple times if there are concurrent move operations on it. So you are right. The use of a transaction would also simplify the code. You would only need to return null from that callback. The issue is, the inner set operation CANNOT fail in this scenario, or you would need to run it synchronously. Because, if it does, you would have lost the original value. – felixy Dec 26 '18 at 06:57
2

you can listen to value event on your child you want to copy it ,, and #onDataChange get reference of new child and set value dataSnapshot to this child like below sample code

FirebaseDatabase.getInstance().getReference("childYouWantToCopy")
                    .addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    FirebaseDatabase.getInstance().getReference("ChildCopyTo").setValue(dataSnapshot.getValue());
                }

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

                }
            });
Mahmoud Abu Alheja
  • 3,343
  • 2
  • 24
  • 41