Been trying for days to connect to Firebase CCS via Smack Library. Nothing has happened. Today, I tried to set up a valueanimator with a duration of 10 seconds to try to reconnect should something happen to the connection. I've tried as best as a I can to Log.d every step of the way, but the logs weren't even showing today. I've got several exceptions on the logs such as: X-OAUTH2 "incorrect/encoding and PARSER has reached end of document". From what I've read, FCM CCS needs to authenticate my connection. Still don't know how to do this with Smack. Even one of the supposed Smack authorities in StackOverflow became silent after I asked him for insight as to how to go about this.
Well my problems are that the connection just closes on its own based on the connectionclosed() overriden method from addConnectionListener on the Smack library:
Well here is my set up: Hopefully someone will point me in the right direction. This is really getting frustrating. Smack seems like a nice library to use for XMPP, but I see very little support for it. Even the lingo of Packet listeners and extensions is abstract. The tutorials online are outdated big time, and the supposed authorities don't even reply back.
Here is my code step by step:
//to set up connection i do this: this thread is called inside onStart()
new Thread(new Runnable(){
XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder();
private Handler umm;
@Override
public void run() {
configBuilder.setSecurityMode(XMPPTCPConnectionConfiguration.SecurityMode.ifpossible);
configBuilder.setServiceName("fcm-xmpp.googleapis.com");
configBuilder.setHost("fcm-xmpp.googleapis.com");//configBuilder.setHost("192.168.1.74");//fcm-xmpp.googleapis.com
configBuilder.setPort(5236);
configBuilder.setCompressionEnabled(false);
configBuilder.setSendPresence(false);
configBuilder.setUsernameAndPassword([email protected],serverKey);
//configBuilder.setDebuggerEnabled(true); <-------wish I knew how to use this
configBuilder.setSocketFactory(SSLSocketFactory.getDefault());
SASLPlainMechanism p = new SASLPlainMechanism();
SASLAuthentication.registerSASLMechanism(p); //ACCORDING TO GOOGLE FCM WE NEED TO HAVE A PLAIN
//MECHANISM
XMPPTCPConnection.setUseStreamManagementDefault(true);
XMPPTCPConnection.setUseStreamManagementResumptionDefault(true);
FCMconnection = new XMPPTCPConnection(configBuilder.build());
//FCMconnection.setDebuggerEnabled(true); <-----------WISH I KNEW HOW TO USE THIS
//THIS MANAGER NEVER WORKED
/*
manager = ReconnectionManager.getInstanceFor(FCMconnection);
manager.setFixedDelay(15);
ReconnectionManager.setDefaultReconnectionPolicy(ReconnectionManager.ReconnectionPolicy.FIXED_DELAY);
manager.enableAutomaticReconnection();
try {
FCMconnection.connect();
FCMconnection.login();
Log.d("Thisi","fadf"+myRegId);
Log.d("here","attempting");
} catch (Exception e) {
Log.d("myerror","JJ: "+e);
e.printStackTrace();
}
*/
umm = yes;
try {
FCMconnection.connect();
Log.v("pony", "white horse"+FCMconnection.getStreamId()+" last: "+FCMconnection.getLastStanzaReceived());
Log.d("user","WW: "+FCMconnection.getUser()+" EE "+FCMconnection.isConnected()+" SS "+
FCMconnection.isSecureConnection());
DeliveryReceiptManager dm = DeliveryReceiptManager // WHO KNOWS WHAT THIS DOES.
//NEVER LOGGED ANYTHING FOR ME
.getInstanceFor(FCMconnection);
dm.setAutoReceiptMode(DeliveryReceiptManager.AutoReceiptMode.always);
dm.addReceiptReceivedListener(new ReceiptReceivedListener() {
@Override
public void onReceiptReceived(final String fromid,
final String toid, final String msgid,
final Stanza packet) {
Log.d("credentials","from: "+fromid + " to: "+toid+" msg: "+msgid+" stanza: " +
packet.toString());
}
});
android.os.Message y4 = android.os.Message.obtain();
y4.what = LOGINTOFCM;
y4.obj = d.toXML();
umm.sendMessage(y4);
} catch (SmackException e) {
e.printStackTrace();
Log.d("pony", "::Dragony: " + e);
} catch (IOException e) {
e.printStackTrace();
Log.d("pony", "Eagle:: " + e);
} catch (XMPPException e) {
e.printStackTrace();
Log.d("pony", "Earthy: " + e);
}
}
}).start();
notice above that i send a message to my onCreate() Handler which says "LOGINTOFCM" once this reaches the handler two methods are started that one of them adds the connectionListener to my FCMconnection object and the other one adds a addAsyncStanzaListener to my FCMconnection object. Inside this method is where I start a valueanimator that tries to login to the FCM CCS
What happens after this is that my connection gets closed, so on first attempt my connection connects according to the logs and FCMconnection.isConnected() returns true. This first attempt is inside onStart(). When I start the valueanimator that attempts to login to FCM CCS my connection has been closed. So, I am actually trying to login without having a connection. Today, I invented a hack to try to reconnect every time it closes: Here's what I tried today, but once again the logs weren't even firing:
I created a valueanimator that will restart itself at the end of the animation. So, in a way it would act as a while loop: its duration was for 10 seconds: Here's the code:
private class reconnect implements Runnable{
private reconnect(){
}
@Override
public void run() {
reconnect_animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
if(!FCMconnection.isConnected()) {
try {
FCMconnection.connect();
FCMconnection.login();
} catch (XMPPException e) {
e.printStackTrace();
} catch (SmackException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Log.d("are", "LL " + FCMconnection.isConnected() + " WW " + FCMconnection.isAuthenticated() + " ID: " + myRegId);
}
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
if(!FCMconnection.isConnected())reconnect_animator.start();
else{
Log.d("conni","WEE: "+FCMconnection.isConnected());
reconnect_animator.start();
}
}
});
}
}
Now inside the connectionClosed method inside the addConnectionListener interface which i set up for my FCMconnection object with the Smack library
I send a message to my onCreate() handler to try to start this animator that will try to reconnect should the connection drop. The call is succesfull to the onCreate() Handler, so my animator starts but it doesn't act like I want to.
Also, I try to log the value of registration token given by the FirebaseRegistrationId service class that they talk about in the FCM docs.
It even seems like this service class doesn't even start even though I documented clearly like the docs say to do. Inside this class I try to change the value of a static string which resides on onCreate() with FirebaseInstanceId.getInstance().getToken(); in onCreate() I give this static string an initial value of chewbaka which remains the same throughout the operation of the application. This leads me to believe that this so important class from Firebase API's is not even called even though is documented clearly as it says in my manifest file.
If anyone has any idea or suggestion please help me. I've tried different tactics, but this outdated Smack examples just don't cut it, and all the abstract lingo of Packets, STanzas, PacketExtensions, ExtensionProvider, Elements and DefaultElementExtensions just makes the job worse.
Once again thanks for trying.
Copyright Notice:Content Author:「i_o」,Reproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/38235918/smack-pitfalls-and-outdated-code-makes-it-nearly-impossible-to-connect-to-fcm-cc