写入规则后无法填充Firebase列表适配器

时间:2016-06-04 18:03:26

标签: android firebase firebase-realtime-database firebase-security

我一直在解决这个问题,现在我决定向社区提问。我的Firebase数据库中有一个位置列表,其中只有选定的用户才能访问。以下是我的Firebase数据库的摘录:

"Locations" : {
   "Location1" : {
     "Users" : "UID1",
     "location" : "Alam Megah",
     "stationNumber" : 1122
   },
   "Location2" : {
     "Users" : "UID1",
     "location" : "Ampang 1",
     "stationNumber" : 1134
   },
   "Location3" : {
     "Users" : "UID2",
     "location" : "Bukit Bintang 1",
     "stationNumber" : 1130
   },
   "Location4" : {
     "Users" : "UID2",
     "location" : "London",
     "stationNumber" : 1130
   },
   "Location5" : {
     "Users" : "UID3",
     "location" : "Paris",
     "stationNumber" : 1130
   },
   "Location6" : {
     "Users" : "UID3",
     "location" : "Singapore",
     "stationNumber" : 1130
   }
 },


 "Users" : {
"UID1" : {
  "UserID" : "User1",
  "Location" : {
    "Location1":true,
    "Location2":true
  },
  "Email" : "user1@abc.com"
},
"UID2" : {
  "UserID" : "User2",
  "Location" : {
    "Location3":true,
    "Location4":true
  },
  "Email" : "user2@abc.com"
},
"UID3" : {
  "UserID" : "User3",
  "Location" : {
    "Location5":true,
    "Location6":true
  },
  "Email" : "user3@abc.com"
}

我已经编写了如下安全规则,以便只有选定的用户才能访问某个位置。

{
"rules":{
"Users":{  
     "$uID":{            
        ".read":"auth != null && auth.uid === $uID",
        ".write":"auth !=null && auth.uid === $uID"
     }
   },
   "Locations":{ 
      "$Location":{  
         ".read":"auth != null && (auth.isAdmin==true || root.child('Users').child(data.child('Users').val()).child('UserID').val()==auth.uid)"
      }
    }
  }
}

我已尝试在“规则”标签下的控制台中在Firebase Simulator中运行此代码,它可以按我的意愿运行。但是,当我想使用Firebase列表适配器在Android的listview中填充此内容时,我无法像以前那样执行此操作,因为现在,我无权访问“位置”节点。如果我授予对“位置”节点的访问权限,则“位置”的所有子节点也会自动获得访问权限。以下是我的位置,位置列表适配器和LocationActivity类的片段:

Locations.class:

public class Locations {
 private String mLocation;
 private int mStationNumber;
 @Exclude
 private String mUser;

 public Locations() {
}
 public Locations(String location, int stationNumber) {
    mLocation = location;
    mStationNumber = stationNumber;
}
 public String getLocation() {
    return mLocation;
}
 public long getStationNumber() {
    return mStationNumber;
 }
}

LocationListAdapter.class

public class LocationListAdapter extends FirebaseListAdapter<Locations> {
 public LocationListAdapter(Activity activity, Class<Locations> modelClass, int modelLayout, Query ref) {
    super(activity, modelClass, modelLayout, ref);
    this.mActivity = activity;
}
@Override
protected void populateView(View v, Locations model, int position) {
    TextView locationName = (TextView) v.findViewById(R.id.locationName);
    TextView locationID = (TextView) v.findViewById(R.id.locationID);

    locationName.setText(model.getLocation());
    locationID.setText(Integer.toString((int) model.getStationNumber()));
 }
}

LocationSelectorActivity.class

public class LocationSelectorActivity extends AppCompatActivity {

private ListView mListView;
private LocationListAdapter mLocationListAdapter;

public LocationSelectorActivity() {
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    DatabaseReference locationRef = FirebaseDatabase.getInstance().getReference().child("Locations");
    mListView = new ListView(this);
    mLocationListAdapter = new LocationListAdapter(this, Locations.class,R.layout.single_location_list,locationRef);

    mListView.setAdapter(mLocationListAdapter);
    setContentView(mListView);
    mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            Locations selectedLocation = mLocationListAdapter.getItem(position);

            if(selectedLocation!=null){
                Intent intent = new Intent(LocationSelectorActivity.this, ChecklistSelectorActivity.class);
                String listId = mLocationListAdapter.getRef(position).getKey();
                intent.putExtra("location",listId);
                startActivity(intent);

            }
        }
    });

}
}

我的问题是,我可以使用其他方法(如果有的话)迭代“地点”列表并使用上述规则填充吗?

我从读数中知道我不能将规则用作过滤器,所以我想做的是拥有一个不同的位置组列表,比如Location1,Location2和Location3,每个都有自己的用户列表和位置孩子们,因此在我的Java代码中创建了不同的POJO和ListAdapter,但是,我认为这是多余的,因为大部分工作都是在客户端本身完成的。我可能是错的,如果有其他方法,请纠正我。

非常感谢你的帮助。

0 个答案:

没有答案