How to know message sending has failed in asmack - android

I am trying to send a message using asmack and I am getting an error like this in log cat:
07-23 13:44:45.759: D/SMACK(20581): RCV (0): <message from='139#192.168.10.241' to='143#192.168.10.241/false' type='error' id='7DOua-233'><body>dgvvvcvcvhcbfbfvgchcbgbhgbhvnhbnvbvbhgbbbbhvbcnvbvbvbvvvcbvcbv hvvvbcvbbhnhjbnnvjbbnnnvnhbnbbbnnn</body><error code='500' type='wait'><resource-constraint xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/><text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'>Your contact offline message queue is full. The message has been discarded.</text></error></message>
This is the code:
if(mConnection!=null)
{
Message msg = new Message(params[0], Message.Type.chat);
msg.setBody(params[1]);
try
{
System.out.println("sending..");
mConnection.sendPacket(msg);
System.out.println("sent!"+msg.getBody());
System.out.println("sent!"+msg.getTo());
flag=true;
}
catch(Exception e)
{
System.out.println("Exception:"+e);
}
}
How can I catch the above log cat error in my own try catch block? In the current case it is returning true even if message sending has failed. How can I know whether the message sending has failed due to the error like above.

Add a packet listner and check the type of packet received. If its an error your message is not delivered.

In your xmpp server go to offline messages settings and set a very high limit for storing offline messages such as 1024 KB and also check always store messages even if the maximum size has been reached.
Hope this works!

Related

Strange Laravel/Stripe/Cartalyst bug where a charge randomly runs twice using the same Stripe token

I've created an Android mobile app which has integrated Stripe to accept card payments. In my Android app, I send to my Laravel API, a bunch of parameters, one of which is a Stripe token.
9 times out of 10, my server handles this as expected. It will create a charge object using Stripe-Cartalyst and create a charge, assuming no exceptions are thrown (such as bad card details, or a server error), my api will then proceed to handle the payment as a success and do some inserts into a DB, after which it will return a 201 HTTP status code back to the client, where I then handle this on the Android side.
The bug (or something I'm doing incorrectly) I've encountered though, happens randomly. Occasionally my API will throw an uncaught exception from Stripe explaining a token (encrypted Stripe card details), can only be used once. I've done some debugging on the Android side and can verify I'm only making 1 HTTP request where I send the token, and have done some Logging on my Laravel API, and have found some strange goings on.
What I've found
On the API, I printed some key moments of the process to a log file.
Print the token variable.
When entering the try block to create the charge object.
If 'Delivery' is selected on the Android app (probably a pointless log here).
Checking some items (this is an array passed from the Android app.
At the end of the charge, before returning the 201 back to the client, print a success message of some kind.
I then proceeded to recreate the bug, after about 20/30 orders it happened, and this is the process that occurred:
First, on the Android app, the following token was sent (and printed out to the console);
tok_1DiK0uKIdjSiVG8mn8CV2iim
After checking, this HTTP request was only triggered once, so I don't think it's an Android issue.
Next, on the API log file, the following occurred:
2018-12-17 11:11:56] local.DEBUG: Token: tok_1DiK0uKIdjSiVG8mn8CV2iim
[2018-12-17 11:11:56] local.DEBUG: Creating Stripe Charge
[2018-12-17 11:11:59] local.DEBUG: Token: tok_1DiK0uKIdjSiVG8mn8CV2iim
[2018-12-17 11:11:59] local.DEBUG: Creating Stripe Charge
[2018-12-17 11:12:00] local.ERROR: There is currently another
in-progress request using this Stripe token (that probably means you
clicked twice, and the other charge is still going through):
tok_1DiK0uKIdjSiVG8mn8CV2iim. This token can not be used again if that
charge is successful.' {"exception":"[object]
(Cartalyst\Stripe\Exception\MissingParameterException(code: 400):
There is currently another in-progress request using this Stripe token
(that probably means you clicked twice, and the other charge is still
going through): tok_1DiK0uKIdjSiVG8mn8CV2iim. This token can not be
used again if that charge is successful.' at
/home/rbfs6nkk73qi/api/prototype/vendor/cartalyst/stripe/src/Exception/Handler.php:123)
[stacktrace]
[2018-12-17 11:12:00] local.DEBUG: Delivery order
[2018-12-17 11:12:00] local.DEBUG: Checking single items
[2018-12-17 11:12:00] local.DEBUG: Card delivery - Order placed via
Android V0.5 app
This shows that from the steps I listed 1-5, the API did: 1,2,1,2,error,3,4,5.
I'm at a complete loss as to why my API would randomly run twice. I've pasted the relevant parts of my API below, to see if there is something obviously wrong that I'm doing. Appreciate any help on this.
One last thing I've tried: I've tried setting the $token variable to null directly after creating the $stripe charge object, which makes me wonder if this is some Cartalyst bug.
if($card) {
$token = $request->token; //Stripe token
Log::debug("Token: ".$token); //Step 1
try {
Log::debug("Creating Stripe Charge"); //Step 2
$stripe->charges()->create([
'currency' => $currency,
'amount' => $amount,
'source' => $token
]);
if(strcmp($delivery,"Delivery") == 0) {
Log::debug("Delivery order"); //Step 3
if($singleItems != null) {
Log::debug("Checking single items"); //Step 4
foreach($singleItems as $key => $value) {
$singleItem = DB::table('items')
->select('name','category','price')
->where('item_id', '=', $key)
->get();
foreach($singleItem as $item) {
DB::table('single_order_items')->insert(['order_number' => $id, 'item'=>$key, 'quantity'=>$value, 'name'=>$item->name, 'category'=>$item->category, 'price'=>$item->price]);
}
}
}
Log::debug("Card delivery - ".$description); //Step 5
return response("Order placed successfully", 201)
->header('Content-Type', 'text/plain');
}
} catch(\Cartalyst\Stripe\Exception\BadRequestException $e) {
//This exception will be thrown when the data sent through the request is mal formed.
$message = $e->getMessage();
Log::debug($message);
return response($message, 306)
->header('Content-Type', 'text/plain');
} catch(\Cartalyst\Stripe\Exception\UnauthorizedException $e) {
//This exception will be thrown if your Stripe API Key is incorrect.
$message = $e->getMessage();
Log::debug($message);
return response($message, 307)
->header('Content-Type', 'text/plain');
} catch(\Cartalyst\Stripe\Exception\InvalidRequestException $e) {
//This exception will be thrown whenever the request fails for some reason.
$message = $e->getMessage();
Log::debug($message);
return response($message, 308)
->header('Content-Type', 'text/plain');
} catch(\Cartalyst\Stripe\Exception\NotFoundException $e) {
//This exception will be thrown whenever a request results on a 404.
$message = $e->getMessage();
Log::debug($message);
return response($message, 309)
->header('Content-Type', 'text/plain');
} catch(\Cartalyst\Stripe\Exception\CardErrorException $e) {
//This exception will be thrown whenever the credit card is invalid.
$message = $e->getMessage();
Log::debug($message);
return response($message, 310)
->header('Content-Type', 'text/plain');
} catch(\Cartalyst\Stripe\Exception\ServerErrorException $e) {
//This exception will be thrown whenever Stripe does something wrong.
$message = $e->getMessage();
Log::debug($message);
return response($message, 311)
->header('Content-Type', 'text/plain');
}
}
After further debugging, a solution was found. It turns out the HTTP library I'm using on the Android side called Volley was sending the request more than once.
Setting the Volley request to have 0 retries seems to have solved the issue:
MyStringRequest.setRetryPolicy(new DefaultRetryPolicy(0,DefaultRetryPolicy.DEFAULT_MAX_RETRIES,DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

Smack Push Notification not working

I am using Smack library to get XMPP pubsub requests in my Android App.
I want to send alert from 1 phone which is received on another phone as push notification popup.
On debugging, control returns null due to this code in Smack 4.2.0 library's ChatManager.java class.
EntityJid userJID = from.asEntityJidIfPossible();
if (userJID == null) {
LOGGER.warning("Message from JID without localpart: '" + message.toXML() + "'");
return null;
}
My from isnt null,ofc... but, my asEntityjidIfPossibe is null.
My Iq is as follows:
<iq
to="pubsub.foo"
from="notifier#foo"
type="set"
id="1523272621323">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
<publish xmlns="http://jabber.org/protocol/pubsub"
node="/home/foo/notifier/c7215880-a36e-4cb9-bdd3-441cf9c29c31/pqr">
<item id="item11523272621323">
<json xmlns="urn:xmpp:json:0">
{"id":"b7da305d-77c2-422a-9c95-7ec8a347192e",
"orgId":"c7215880-a36e-4cb9-bdd3-441cf9c29c31",
"user_id":"f0622ed6-860f-4f4e-9b11-c4ab6cb8cd66",
"username":"xyz",
"subject":"Message",
"body":"hello all",
"priority":"NORMAL",
"ack_required":false,
"users":["pqr"],
"replyTo":["/home/foo/notifier/c7215880-a36e-4cb9-bdd3-441cf9c29c31/xyz",
"/home/foo/notifier"]}
</json>
</item>
</publish>
</pubsub>
</iq>
All I want is to see if message sent is recieved or not? And how to get data to process it...Data is sent perfectly on the server from the sending phone.
On recieving device,
I get this message TWICE,
Message from JID without localpart: '<message to='xyz#foo/5301412210663914056363834' from='pubsub.foo'><event xmlns='http://jabber.org/protocol/pubsub#event'><items node='/home/foo/notifier/c7215880-a36e-4cb9-bdd3-441cf9c29c31/xyz'><retract id='item11523351450156'/></items></event></message>'

Message id issue connecting chat between iOS and Android in Quickblox

I'm having an issue connecting an iOS and Android device with their corresponding QBChat libraries, with the message ID's.
Message objects in Quickblox's iOS library are defined as QBChatMessage objects, that doesn't exist in Quickblox's Android library (which delegates them to a Message class in SMACK library).
The problem is that QBChatMessage class manages message id's as integers, while Message class manages them as Strings. Every message sent from my Android device has a 7-character unique string + a number with the message's position in SMACK chat. When my iPhone receives the message, its ID is a number with the ID from SMACK parsed as much as it could, as in this communication sample (taken from the Android device):
SENT <message id="D64u5-4" to="102521-1799#chat.quickblox.com" from="132505-1799#chat.quickblox.com/Smack" type="chat"><body>{"content":{"text":"hello"},"type":1}</body><thread>7J9230</thread></message>
SENT <message id="D64u5-5" to="102521-1799#chat.quickblox.com" from="132505-1799#chat.quickblox.com/Smack" type="chat"><body>{"content":{"text":"yeah"},"type":1}</body><thread>7J9230</thread></message>
SENT <message id="D64u5-6" to="102521-1799#chat.quickblox.com" from="132505-1799#chat.quickblox.com/Smack" type="chat"><body>{"content":{"text":"test"},"type":1}</body><thread>7J9230</thread></message>
RCV <message id="0" from="102521-1799#chat.quickblox.com" type="chat" xmlns="jabber:client" to="132505-1799#chat.quickblox.com"><body>{"content":{"text":"hello"},"type":1}</body></message>
RCV <message id="1" from="102521-1799#chat.quickblox.com" type="chat" xmlns="jabber:client" to="132505-1799#chat.quickblox.com"><body>{"content":{"text":"yeah?"},"type":1}</body></message>
RCV <message id="2" from="102521-1799#chat.quickblox.com" type="chat" xmlns="jabber:client" to="132505-1799#chat.quickblox.com"><body>{"content":{"text":"yeah!"},"type":1}</body></message>
Message's ID is important for me, in order of database storage. How is this possible? What should I do to solve this issue?
Thanks, kind regards! :)
Daniel, sounds good.
Is changing type of QBChatMessages.ID to NSString will solve your issue?
Will do that in next release. If you haven't time to wait - just write with your request to assist#quickblox.com, will make special build of SDK for you
Below is my Android code for group chat:
/* Sends messages */
public void sendChatMessage(String text)
{
Message message = muc.createMessage();
message.setBody(text);
message.setPacketID("ABC_1");
muc.sendMessage(message);
}
/* Listens for messages */
public void receiveMessage()
{
muc.addMessageListener(new PacketListener() {
public void processPacket(Packet packet)
{
final Message message = (Message) packet;
log.i("packed id: ", packet.getPacketID());
log.i("message id: ", message.getPacketID());
}
});
}
The output I see in logcat is
packet id: null
message id: null
Could you please tell me why the IDs are null? Am I missing something here?

asmack pubsub getItems error

I'm trying to publish some information to server using the Pubsub nodes.unfortunately,I failed to retrieve the node that published before.Just very similar as the problem in the following link:
http://community.igniterealtime.org/message/199690#199690
to be specific, the code snippets like following :
try {
LeafNode node = mPubsub.getPEPNode(USEINFONODE,mFrom);
if(null != node){
List<Item> items = node.getItems();
Log.i("items",items.toString());
}
} catch (XMPPException e) {
Log.e("userInfoExtension","error : and the error is " + e.toString());
}
and the output error is no resposne from server.
the output of the debug is just like this:
<iq id="B9tI0-4" to="pubsub.mymachine" type="get"><query xmlns="http://jabber.org/protocol/disco#info" node="theNode"></query></iq>
<iq id="B9tI0-5" to="pubsub.mymachine" type="get"><pubsub xmlns="http://jabber.org/protocol/pubsub"><items node='theNode'/></pubsub></iq>
However according to the link mentioned above, the expected iq stanza shall be like this:
<iq type='get'
from='notifyserver#mymachine'
to='pubsub.mymachine'
id='items1'>
<query xmlns='http://jabber.org/protocol/disco#items'
node='theNode'/>
</iq>
so It shows that I miss the from field in the iq stanza,I'm wondering how can I put the from ='client#server' into the iq stanza. I have tried asmack libraries including :
asmack-android-7.jar , asmack-android-7-beem.jar asmack-android-16-beem.jar,all failed.
Can anyone help with this? Thanks very much.
I have found that it has something to do with receiving the packet. actually I have received the packet that I needed, the trouble is that the packet may can not be processed by smack in somewhere, and it will throw no response from sever exception.
so I think the problem is actually not receiving incoming packet correctly .
so does in my other question:
http://stackoverflow.com/questions/14357707/how-to-send-and-listen-to-custom-xmpp-presence-packet-with-asmack-the-library
I'm sorry to mislead you ! the error is caused by my extension provider which lead the parsing
packet into an endless loop, thus ,caused the no response from server exception.

Sending and Receiving IQ Packets ASMACK/SMACK Android XMPP

I would highly appreciate if someone can help me how to recieve iq packets with ASMACK, i am sending raw iq packets but not able to receive it,
I have registered the iq packets programatically before making a connection but still not getting reponse,
pm.addIQProvider("vCard", "vcard-temp", new VCardProvider());
final IQ iq = new IQ() {
public String getChildElementXML() {
return "<iq from='test#XX.XX.XX.XX' id='v1' to='test#XX.XX.XX.XX' type='get'><vCard xmlns='vcard-temp'/></iq>";
}
};
iq.setType(IQ.Type.GET);
connection.sendPacket(iq);
connection.addPacketListener(new MyPacketListener(),new PacketTypeFilter(IQ.class));
First of all, try setting your packet listener before you send the packet. It is an asynchronous protocol and it is possible that the response is being returned before your listener is setup to receive it.
Then try setting -DsmackDebugEnabled=true to check that there is an actual response to your send.
You can implement a Packet Listner method, the processPacket(Packet packet) method will give you the incoming packets.
Here is a stack thread which explains the same issue aSmack - Packet to XML using Packet Listener outputs nullable elements

Categories

Resources