问题
I am currently trying to implement a trading system for my unity android app using firebase. For that I have to check, if a player pressed the buy button for one trade, if the selected trade is still available in the firebase database.
The way it is supposed to work is, that the player who wants to buy something checks in the corresponding trade, if the buyerId is still empty, and if so puts his own id in there. I've set up the firebase rules, so that the buyerId and buyerName can only be set once.
So that's now the code I was trying to use:
if (!reference.Child("trading").Child("trade|" + currentTrade.date).Child("buyerId").SetValueAsync(userId).IsCanceled)
{
Debug.Log("trade should be successfull");
}
else
{
Debug.Log("trade should have failed");
}
Well the problem is now, that it doesn't matter if the buyerId is empty or not, the unity console always prints out, that the trade was succesfully. But I do actually get a logWarning in the console, that the permission was denied. My question is now, how do I detect it properly if the buyerId was already set?
My database structure:
{
"currentVersion" : {
"FileSize" : 58010,
"ReleaseDate" : "01.08.19",
"Version" : "1.10.7.9"
},
"trading" : {
"trade|1570361586" : {
"amount" : 5,
"buyerId" : "",
"buyerName" : "",
"date" : 1570361586,
"item" : 7,
"price" : 6,
"sellerId" : "1234",
"sellerName" : "testA"
},
"trade|1570363226" : {
"amount" : 1,
"buyerId" : "9876",
"buyerName" : "testB",
"date" : 1570363226,
"item" : 7,
"price" : 1,
"sellerId" : "1234",
"sellerName" : "testA"
},
"trade|1570467885" : {
"amount" : 1,
"buyerId" : "4545",
"buyerName" : "testC",
"date" : 1570467885,
"item" : 7,
"price" : 2,
"sellerId" : "1234",
"sellerName" : "testA"
}
}
}
My database rules:
{
"rules": {
"currentVersion" : {
".write" : false,
".read" : true
},
"trading" : {
".read" : true,
"$trade" : {
".write" : "!data.exists()",
"buyerName" : {
".write" : "data.val() == '' && newData.val() != ''"
},
"buyerId" : {
".write" : "data.val() == '' && newData.val() != ''"
},
"sellerName" : {
".write" : false
},
"sellerId" : {
".write" : false
},
"amount" : {
".write" : false
},
"item" : {
".write" : false
},
"price" : {
".write" : false
}
}
}
}
}
回答1:
This looks odd to me:
if (!reference.Child("trading").Child("trade|" + currentTrade.date).Child("buyerId")
.SetValueAsync(userId).IsCanceled)
Since you're calling SetValueAsync
, the value is set to the database asynchronously. The chances of IsCanceled
being true
right after your call to SetValueAsync
are incredibly small.
As the documentation on knowing when your data is committed explains, you'll want to wait until the Task
that is returned from SetValueAsync
is completed.
Something like this:
reference.Child("trading").Child("trade|" + currentTrade.date).Child("buyerId")
.SetValueAsync(userId).).ContinueWith(task => {
if (task.IsFaulted)
{
// Handle the error...
}
来源:https://stackoverflow.com/questions/58274615/check-whether-the-writing-permission-was-accepted-or-denied