Из того, что я понимаю:
1) У вас есть специальное приложение для добавления предложений (вами).
2) У вас есть другое приложение для чтенияпредложения (по пользователям).
3) Если это так, то оба приложения используют один и тот же проект.
4) Когда пользователь нажимает предложение, он / она получает предложение, затем вы удалите предложение из базы данных.
5) Теперь, когда 2 пользователя щелкают одно и то же предложение, у него нет времени на удаление предложения из списка другого пользователя, поэтому они в итоге получают одно и то же.предложение.
Теперь кажется, что вы не хотите, чтобы пользователи получали одинаковые предложения, и проблема действительно заключается в сроках.
Возможное решение:
1) Когда пользователь щелкает предложение, вы запускаете ValueEventListener () для узла offers
в базе данных и проверяете, существует ли предложение.
2) Если предложение существует, дайте ему /ей предложение и удалите его.
3) Теперь, когда 2 пользователя нажимают одно и то же предложение, ValueEventListener, который я используюked about предоставит вам некоторое время, прежде чем реагировать.
4) Таким образом, пользователи не должны получать одинаковые предложения.
Надеюсь, что это решит вашу проблему.
ОБНОВЛЕНИЕ:
Поскольку это условие гонки между пользователями, самое время поговорить о транзакциях.Firebase предоставляет хороший способ для непосредственного чтения и записи одновременных обновлений на один и тот же узел (как в вашем случае).
Я хочу, чтобы ваша база данных была такой:
Offers
|
|------offer_id_1
|
|-----taken:false
|-----......
|-----......
|
|-------offer_id_2
|
|------taken:false
|------......
|------......
Позвольте мне объяснитьВ приведенной выше структуре каждое предложение, которое вы публикуете в другом приложении, по умолчанию будет иметь флаг taken
, и по умолчанию оно должно иметь значение false
.
Теперь, как вы видите выше offer_id_1
иoffer_id_2
- это push-идентификатор или случайный идентификатор, указанный для предложения (когда пользователь нажимает на предложение, вы должны получить ссылку на этот ключ .... Я полагаю, вы знаете, как это сделать).
Перед тем, как мы начнем курс, у вас должен быть класс модели для ваших постов, мы назовем его Offer
это просто класс:
public class Offer{
public boolean taken;
......
......
}
Следующая функция - это то, что вы будете вызывать после того, как кто-то нажал на предложение (мыбудет использовать транзакцию):
public void RunTransactionFor(String offer_id){
//first refer to your offers
DatabaseReference offers_ref = FirebaseDatabase.getInstance().getReference().child("offers").child(offer_id);
//run a transaction (a transaction is fast it reads and writes directly)
offer_ref.runTransaction(new Transaction.Handler() {
@Override
public Transaction.Result doTransaction(MutableData mutableData) {
//this is a ref to the offer class
Offer offer = mutableData.getValue(Offer.class);
if (offer == null) {
return Transaction.success(mutableData);
}
if(offer.taken == false){
//take the offer
offer.taken = true;
//show a message
Toast.makeText(context, "you took the offer",...).show();
//now you can remove the offer
offers_ref.setValue(null);//or delete it your way
}else{
//too late the offer is taken
Toast.makeText(context, "too late the offer is gone",...).show();
//do nothing
}
// Set value and report transaction success
mutableData.setValue(offer);
return Transaction.success(mutableData);
}
@Override
public void onComplete(DatabaseError databaseError, boolean b,
DataSnapshot dataSnapshot) {
// Transaction completed
}
});
}
Теперь, когда пользователь щелкает предложение в списке, сохраните идентификатор предложения и передайте его вышеуказанной функции следующим образом:
//after user clicks
String offer_id = .......
//run transaction
RunTransactionFor(offer_id);
Примечание: транзакции работают толькоКроме того, они не могут работать в автономном режиме.