Retrieving data from FireBase Realtime Database and using it - kotlin

I want to retrieve data from my firebase database, then use that data (which is a Int) in a sum, and then update the database with the answer.
This is what I have so far
This is also in a separate class
database = FirebaseDatabase.getInstance().getReference("Texas")
database.child("Texas").get().addOnSuccessListener {
if (it.exists()){
var number = it.child("Number").value
if (number == Int || number == Long){
number += 1
}
}else{
Log.e(TAG, "Invalid type transition $geofenceTransition")
}
}.addOnFailureListener {
Log.e(TAG, "Invalid type transition $geofenceTransition")
}
At the += sign I get a receiver type mismatch
Please help

Related

Zero-knowledge sequencing of messages

I have multiple servers (for redundancy) sending data to clients. The clients need to process these messages in sequence and ignore duplicates.
We use external information to determine a special sequencing string that is deterministic across all our servers, as it would be too slow to keep the servers in sync.
The sequencing strings generated have remnants of top-secret information in them, and we can't reveal them to the clients.
Suppose the sequencing string just contains an integer. Is there a way of hashing this data such that the clients can order the messages without learning any additional information about its content?
Suppose a more complicated sequence string is used. The string is split into sub-sequences, and each sub-sequence is given a category, something like "a:12477/t:637" and "a:12477/e:456", where the comparison function between sequences is given below. Is it possible to hash the sequencing string in such a way that even a complicated function like this can operate on the data and nothing else?
JavaScript pseudo-code:
function compare(seq_a: string, seq_b: string) {
function decode(seq) {
seq_a.split("/").map(segment => {
let [category, sub_seq] = segment.split(":");
return { category, sub_seq: Number(sub_seq) }
});
}
let a = decode(seq_a);
let b = decode(seq_b);
for (let i = 0; i < Math.max(a.length, b.length); i++) {
let segment_a = a[i] || { category: "empty", sub_seq: 0 };
let segment_b = b[i] || { category: "empty", sub_seq: 0 };
if (segment_a.category != segment_b.category) {
return "UNKNOWN";
}
if (segment_a.sub_seq > segment_b.sub_seq) {
return "A";
} else if (segment_a.sub_seq < segment_b.sub_seq) {
return "B";
} else if (segment_a.sub_seq == segment_b.sub_seq) {
continue;
}
}
return "UNKNOWN";
}
I have very little knowledge in the cryptographic and zero-knowledge area so there's nothing I have yet tried, so the furthest I have gotten is just realizing the idea of what is needed.

Nested Loop select the minimum defined value asp.net

I have a list of states, which are defined to be ordered by min to max. the sequence is the following:
Cancelled - complete - draft - reservation - reserved - ordered - confirmed
So the cancelled is the minimum state, and confirmed is the maximum state. I may have different instances with different states, so I use a for-each loop to run through all states, and select the minimum state present in the loop.
That is: if in a list I have states [complete, reserved, draft, ordered] I need to check all the values and select complete -as it appears to be the minimum state. OR
if I have [reserved, confirmed, ordered, draft, cancelled, confirmed, confirmed] I need to select the cancelled value, as it appears to be the minimum.
I am doing the following check, but it does not seem to be working:
string globstatus = " ";
foreach (var currentstatus in list)
{
if (currentstatus == "cancelled")
{
globstatus = "cancelled";
}
else
{
if (globstatus == "cancelled")
{
return globstatus;
}
else
{
if (currentstatus == "complete")
{
globstatus = "complete";
}
else
{
if (globstatus == "complete")
{
return globstatus;
}
else
{
if (currentstatus == "draft")
{
globstatus = "draft";
}
else
{
if (globstatus == "reservation")
{
return globstatus;
}
else
{
if (currentstatus == "reserved")
{
globstatus = "reserved";
}
else
{
if (globstatus == "ordered")
{
return globstatus;
}
else
{
if (currentstatus == "confirmed")
{
globstatus = "confirmed";
}
else
{
return currentstatus;
}
}
}
}
}
}
}
}
}
}
return globstatus;
What can be the best solution to achieve the desired behavior?
I find a rule of thumb helpful that if I need more than three levels of braces, I need to rethink my code. It's hard to follow, easy to make mistakes, and a nightmare to debug. I suggest that applies here - trying to follow the flow of what all those nested if..else statements is extremely difficult.
Using Enum
My preferred solution is to achieve this using an Enum, e.g.:
var list = new List<Status>
{
Status.Complete,
Status.Draft,
Status.Draft,
Status.Confirmed
};
var minStatus = (Status)list.Select(l => (int)l).Min();
// minStatus = Status.Complete
public enum Status
{
Cancelled,
Complete,
Draft,
Reservation,
Reserved,
Ordered,
Confirmed
}
How it works: by default Enums give each value a zero-based integer, i.e. Cancelled = 0, Complete = 1 and so on. You can override this with your own values if you wish (e.g. 1/2/4/8/16 if you want to combine multiple values).
I recommend using Enum types for things like this, rather than strings. It helps avoid typos, gives someone else looking at your code a clear understanding of how your program works and its flow, and represents hierarchy in a way in which simple strings don't. (For example - does 'complete' come before or after 'draft'? Without context, I imagine most people would say after, but in this case it comes before - that is much more obvious when using an Enum.)
Parse strings to Enum
However if the statuses have to be strings, you could parse them into an enum like so:
var stringList = new List<string>
{
"complete",
"draft",
"draft",
"confirmed",
"this will be ignored"
};
var statusList = new List<int>();
foreach (var str in stringList)
{
if(Enum.TryParse(typeof(Status), str, ignoreCase: true, out object? parsed) && parsed is Status status)
{
statusList.Add((int)status);
}
}
var minStatus = (Status)statusList.Min();
// minStatus = Status.Complete
However, if it's possible to refactor your code to use the Enum in the first place, that would be a better solution, and much quicker as parsing strings has an overhead that would be good to avoid.

How do I get a single document from a Firestore query within a loop

In my app I am running a for loop in my Firestore query. this query itself is meant to only return documents where the criteria of brand and location are met (String values) AND where a counter ("deal_number") located in the document is > than a comparative counter in users collections (Login.deal_number).
So essentially, I search the user collection for the last counter number and use that as a logical check against the counter in the deal id
menuref = FirebaseFirestore.getInstance()
menuref.collection("Users").whereEqualTo("uid", userid)
.addSnapshotListener { value, task ->
if (task != null) {
return#addSnapshotListener
}
for (document in value!!) {
val seller_brand = document.getString("brand")!!
val seller_location = document.getString("location")!!
val deal_num = document.getLong("last_deal_num")!!
//Login.deal_number is a companion object
Login.deal_number = deal_num
Log.d("Firestore_brand", seller_brand)
Log.d("Firestore_location", seller_location)
Log.d("lastdealnum", "${Login.deal_number}")
menuref.collection("Car_Deals").whereEqualTo("brand", seller_brand).whereEqualTo(seller_location, "True").whereGreaterThan("deal_number",Login.deal_number)
.addSnapshotListener { value, task ->
if (task != null) {
return#addSnapshotListener
}
counter_deal = 0
for (document in value!!) {
val new_deal_num = document.getLong("deal_number")!!
Log.d("dealnumnew", "$new_deal_num")
if (new_deal_num == Login.deal_number) {
counter_deal = counter_deal + 1
break
} else if (new_deal_num < Login.deal_number) {
counter_deal = counter_deal + 1
break
}
else if (new_deal_num > Login.deal_number && counter_deal < 1) {
Log.d("Tag_counter_deal","${counter_deal}")
Log.d("Tag_newdeal_num","${new_deal_num}")
Log.d("Tag_userdeal_num","${Login.deal_number}")
counter_deal = counter_deal + 1
newdealnumref =
FirebaseFirestore.getInstance().collection("Users")
newdealnumref.document(userid)
.update("last_deal_num", new_deal_num)
.addOnSuccessListener {
}.addOnFailureListener { e ->
Log.w(
"firestore_create_error",
"Error writing to document",
e
)
}
Log.d("newdealbrand", "$seller_brand $seller_location")
Log.d("newdeal", "New deal found")
dealCreatedNotificationChannel() // this is the android O channel creation
CodetoRunforNotification() // this is the code to run for the notification. generic, havent changed anything according to normal notification creation
with(NotificationManagerCompat.from(this)) {
notify(notify_counter, builder)
notify_counter++
}
counter_deal = 0
break
}
}
}
}
}
For the above, why does Firestore create multiple notifications when there should only be a single event, is it because of the way the filter does not seem to apply correctly. Is it due to the same effect as you would have with a recyclerview/listview whereby you need to clear an array do prevent duplicates that meet the criteria?
This seems to be a common trend with running a notification based on a Firestore query. Is this even possible? I have tried all sorts of breaks in the for loop but keep getting multiple hits on the same document. I tried use the counter_deal to limit the amount of notifications sent once the snapshot is triggered with no luck.

Replacing UUID of player to player's name

I am trying to send a message to the player with his saved friends. These friends are saved in a .yml file, but only the UUIDS of each individual player.
I am then trying to replace the UUID or convert it to the players name when the message is displayed (if that made sense)
CODE:
p.sendMessage("§7▄▄▄▄▄▄▄▄▄▄▄▄§aFriend System - page 1 of 1§7▄▄▄▄▄▄▄▄▄▄▄▄");
int i = 1;
int length = cfg.getList(p.getUniqueId() + ".Friends").size();
if (length != 0)
{
while (i <= length)
{
String uuid = (String)cfg.getList(p.getUniqueId() + ".Friends").get(i - 1);
ProxiedPlayer p2 = ProxyServer.getInstance().getPlayer(UUID.fromString(uuid));
if (p2 != null)
{
TextComponent prefix = new TextComponent(Main.prefix);
TextComponent join = new TextComponent("§a§lONLINE");
prefix.addExtra("§9" + p2.getName());
prefix.addExtra(" ");
prefix.addExtra(join);
p.sendMessage(prefix);
}
else
{
String name = getNamebyUUID(uuid);
if (name != null)
{
p.sendMessage(Main.prefix + "§9" + name + " §c§lOFFLINE");
Main.names.put(uuid, name);
}
else if (Main.names.containsKey(uuid))
{
p.sendMessage(Main.prefix + "§9" + (String)Main.names.get(uuid) + " §8[§c§lOFFLINE§8]");
}
else
{
p.sendMessage(Main.prefix + "§cThis is not a valid player!");
}
}
i++;
}
}
else
{
p.sendMessage(Main.prefix + "§cYou don't have any friends.");
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
Related Question: Get Offline Player by UUID
If the Player is online:
String playerUUID;
Bukkit.getPlayer(playerUUID).getDisplayName();
If the Player is offline:
Not trully possible. The Player can change names at any time, and Bukkit can't keep that information and keep updating all the player's name whenever they change.
You can either use the online-player-only method above, or store the player's name together with the uuid.
#UPDATE
As stated by the user Pokechu22, Bukkit does save the last name the user used before logging out. It can be retrieved this way:
OfflinePlayer off = Bukkit.getOfflinePlayer(String uuid);
String lastKnownName = off.getName();
But be very careful! It might not be the up-to-date name of the player.

How to check forwarded Packets in UDPBasicApp in Omnet

How can I modify UDPBasicApp to find duplicates in the messages recieved?
I made these changes to the class UDPBasicApp.cc to add an extra step to check recieved udp data packets like below, but I see no effect in .sca/.vec and does not even show bubbles.
Where could the error be?
void UDPBasicApp::handleMessageWhenUp(cMessage *msg)
{
if (msg->isSelfMessage()) {
ASSERT(msg == selfMsg);
switch (selfMsg->getKind()) {
case START:
processStart();
break;
case SEND:
processSend();
break;
case STOP:
processStop();
break;
default:
throw cRuntimeError("Invalid kind %d in self message", (int)selfMsg->getKind());
}
}
else if (msg->getKind() == UDP_I_DATA) {
// process incoming packet
//-----------------------------------------------------Added step
//std::string currentMsg= "" + msg->getTreeId();
std::string currentPacket= PK(msg)->getName();
if( BF->CheckBloom(currentPacket) == 1) {
numReplayed++;
getParentModule()->bubble("Replayed!!");
EV<<"----------------------WSNode "<<getParentModule()->getIndex() <<": REPLAYED! Dropping Packet\n";
delete msg;
return;
}
else
{
BF->AddToBloom(currentPacket);
numLegit++;
getParentModule()->bubble("Legit.");
EV<<"----------------------WSNode "<<getParentModule()->getIndex() <<":OK. Pass.\n";
}
//-----------------------------------------------------------------------------
processPacket(PK(msg));
}
else if (msg->getKind() == UDP_I_ERROR) {
EV_WARN << "Ignoring UDP error report\n";
delete msg;
}
else {
throw cRuntimeError("Unrecognized message (%s)%s", msg->getClassName(), msg->getName());
}
if (hasGUI()) {
char buf[40];
sprintf(buf, "rcvd: %d pks\nsent: %d pks", numReceived, numSent);
getDisplayString().setTagArg("t", 0, buf);
}
}
Since I don't have enough context about the entities participating in your overall system, I will provide the following idea:
You can add a unique ID to each message of your application by adding the following line to your applications *.msg:
int messageID = simulation.getUniqueNumber();
Now on the receiver side you can have an std::map<int, int> myMap where you store the <id,number-of-occurences>
Each time you receive a message you add the message to the std::map and increment the number-of-occurences
if(this->myMap.count(myMessage->getUniqueID) == 0) /* check whether this ID exists in the map */
{
this->myMap.insert(std::make_pair(myMessage->getUniqueID(), 1)); /* add this id to the map and set the counter to 1 */
}
else
{
this->myMap.at(myMessage->getUniqueID())++; /* add this id to the map and increment the counter */
}
This will allow you to track whether the same message has been forwarded twice, simply by doing:
if(this->myMap.at(myMessage->getUniqueID()) != 1 ) /* the counter is not 1, message has been "seen" more than once */
The tricky thing for you is how do you define whether a message has been seen twice (or more).