mahoone
mahoone

Reputation: 33

How to link each user to their data in Firebase?

I'm trying to set up an order placing system.

Once the user is verified via email, it can create/update/delete order. Order is saved into Firebase Real-time Database and users are saved in Authentication.

I would like to allow user to only see/edit orders that were placed by this specific user. Basically make use of UserUID from Authentication section.

public class FirebaseDatabaseHelper {
    private FirebaseDatabase mDatabase;
    private DatabaseReference mReferenceOrders;
    private List<Order> orders = new ArrayList<>();

    public interface DataStatus{
        void DataIsLoaded(List<Order> orders, List<String> keys);
        void DataIsInserted();
        void DataIsUpdated();
        void DataIsDeleted();
    }

    //Initialize Database object

    public FirebaseDatabaseHelper() {
        mDatabase = FirebaseDatabase.getInstance();
        mReferenceOrders = ((FirebaseDatabase) mDatabase).getReference("order");
    }

    public void readOrders(final DataStatus dataStatus){
        mReferenceOrders.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                orders.clear();
                List<String> keys = new ArrayList<>();
                for(DataSnapshot keyNode : dataSnapshot.getChildren()) {
                    keys.add(keyNode.getKey());
                    Order order = keyNode.getValue(Order.class);
                    orders.add(order);
                }
                dataStatus.DataIsLoaded(orders,keys);
            }

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

    public void addOrder(Order order, final DataStatus dataStatus) {
        String key = mReferenceOrders.push().getKey();
        mReferenceOrders.child(key).setValue(order).addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                dataStatus.DataIsInserted();
            }
        });
    }

    // Update and Delete methods

    public void updateOrder(String key, Order order, final DataStatus dataStatus){
        mReferenceOrders.child(key).setValue(order).addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                dataStatus.DataIsUpdated();
            }
        });
    }

    public void deleteOrder(String key, final DataStatus dataStatus){
        mReferenceOrders.child(key).setValue(null).addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                dataStatus.DataIsDeleted();
            }
        });
    }
}

Here's what I was thinking:

When a user creates a new order then a UserUID is added to a database and nested inside 'order' so now each order can be assigned to a user that created it.

Screenshot of Firebase Realtime database: order

Now the next step would be to display this order to a user that created it but only if cust_id (in order) matches UserUID of a logged in user. Would that be a good approach?

Upvotes: 0

Views: 542

Answers (2)

mahoone
mahoone

Reputation: 33

I have added a user_id to an 'order' in the Firebase database so each order can be assigned to its user.

I got the parameter for user_id by fetching a UserUID from an Authentication section of Firebase when a new user is logged/signed in.

Screenshot of UserUID in Authentication section of Firebase

I got this value in my code by adding the following:

  private FirebaseAuth mAuth;

  order.setUser_id(mAuth.getCurrentUser().getUid());

Once I got the user_id assigned to each order I've created a following if statement which is implemented in my readOrders function which you can see in my original post above:

public void readOrders(final DataStatus dataStatus){
        mReferenceOrders.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                orders.clear();
                List<String> keys = new ArrayList<>();
                for(DataSnapshot keyNode : dataSnapshot.getChildren()) {
                    keys.add(keyNode.getKey());
                    Order order = keyNode.getValue(Order.class);
                    **if (order.getUser_id().equals(mAuth.getUid())) {
                        Log.d("FirebaseDatabaseHelper", "match");
                        orders.add(order);
                    }else {
                        Log.d("FirebaseDatabaseHelper", "error");
                    }**
                }
                dataStatus.DataIsLoaded(orders,keys);
            }

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

So basically now when the new user logs in, there will be nothing to show because the user_id won't match with any of the user_id's inside Order database.

I'm not sure how efficient this method will be when more users/orders will be added so I'll have to do some testing.

Please advise if this is the best approach!

Upvotes: 1

Panicum
Panicum

Reputation: 824

Yes, it is a good approach, now you need to add to your Firebase Realtime Database now branch with your users data based on userUID, like this:

enter image description here

Thanks to this you will be able to connect your users with their orders data and besides you can save here more specific user data like "how many orders user create", "how many orders are active" etc.

Upvotes: 1

Related Questions