1

I have started to develop chat application. I needed to check user has registered or not in xmpp server.So when user trying to register,I want check user has already registered or not in xmpp server. After xmpp server connected successfully,Tried to search as number using Usersearchmanager.But Getting error as

java.lang.IllegalArgumentException: Must have a local(user) JID set.Either you didn 't configure one or you where not connected at least once
 at org.jivesoftware.smack.filter.IQReplyFilter. < init > (IQReplyFilter.java: 94)
 at org.jivesoftware.smack.AbstractXMPPConnection.createPacketCollectorAndSend(AbstractXMPPConnection.java: 699)
 at org.jivesoftware.smackx.search.UserSearch.getSearchForm(UserSearch.java: 73)
 at org.jivesoftware.smackx.search.UserSearchManager.getSearchForm(UserSearchManager.java: 71)
 at com.techno.samplechat.Myxmpp.searchUsers(Myxmpp.java: 335)
 at com.techno.samplechat.Myxmpp$XMPPConnectionListener.connected(Myxmpp.java: 284)
 at org.jivesoftware.smack.AbstractXMPPConnection.callConnectionConnectedListener(AbstractXMPPConnection.java: 1162)
 at org.jivesoftware.smack.tcp.XMPPTCPConnection.connectInternal(XMPPTCPConnection.java: 850)
 at org.jivesoftware.smack.AbstractXMPPConnection.connect(AbstractXMPPConnection.java: 365)
 at com.techno.samplechat.Myxmpp$1.run(Myxmpp.java: 117)
 at java.lang.Thread.run(Thread.java: 818)

Code:

private void CreateAccount() {


    org.jivesoftware.smackx.iqregister.AccountManager am = org.jivesoftware.smackx.iqregister.AccountManager
        .getInstance(connection);
    am.sensitiveOperationOverInsecureConnection(true);
    Map < String, String > attributes = new HashMap < String, String > ();

    attributes.put("username", loginUser);
    attributes.put("email", "Manikandan.s@technoduce.com");
    attributes.put("password", passwordUser);
    attributes.put("name", UserName);
    try {
        if (am.supportsAccountCreation()) {


            am.createAccount(
                loginUser,
                passwordUser,
                attributes);

            login();





        }
    } catch (SmackException.NoResponseException e) {
        e.printStackTrace();
    } catch (XMPPException.XMPPErrorException e) {
        e.printStackTrace();
    } catch (SmackException.NotConnectedException e) {
        e.printStackTrace();
    }


}

private void login() {
    try {
        connection.login(loginUser, passwordUser);
        Log.i("LOGIN", "Yey! We're connected to the Xmpp server!");

    } catch (XMPPException e) {
        e.printStackTrace();
    } catch (SmackException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    ChatManager.getInstanceFor(connection).addChatListener(this);

}

@
Override
public void chatCreated(Chat chat, boolean createdLocally) {
    Log.i("service", "chatCreated()");
    System.out.println("+chatList++" + chat.getParticipant());
    chat.addMessageListener(this);
}

@
Override
public void entriesAdded(Collection < String > addresses) {

}

@
Override
public void entriesUpdated(Collection < String > addresses) {

}

@
Override
public void entriesDeleted(Collection < String > addresses) {

}

@
Override
public void presenceChanged(Presence presence) {

}

@
Override
public void processMessage(Chat chat, Message message) {

    if (message.getType() == Message.Type.chat || message.getType() == Message.Type.normal) {
        if (message.getBody() != null) {
            // Toast.makeText(this,message.getFrom() + " : " + message.getBody(),Toast.LENGTH_LONG).show();
            System.out.println("++From++" + message.getFrom() + "++Body++" + message.getBody());

        }
    }

}

@
Override
public void pingFailed() {

}

private class XMPPConnectionListener implements ConnectionListener {

    @
    Override
    public void connected(XMPPConnection connection) {
        Log.e("success", "Connected");


        try {
            searchUsers(loginUser);
        } catch (SmackException.NotConnectedException e) {
            e.printStackTrace();
        } catch (XMPPException.XMPPErrorException e) {
            e.printStackTrace();
        } catch (SmackException.NoResponseException e) {
            e.printStackTrace();
        }
        //  CreateAccount();



    }




    @
    Override
    public void authenticated(XMPPConnection connection, boolean resumed) {

    }

    @
    Override
    public void connectionClosed() {

    }

    @
    Override
    public void connectionClosedOnError(Exception e) {
        System.out.println("+_" + e.toString());
    }

    @
    Override
    public void reconnectionSuccessful() {

    }

    @
    Override
    public void reconnectingIn(int seconds) {

    }

    @
    Override
    public void reconnectionFailed(Exception e) {

    }
}
public void searchUsers(String userName) throws SmackException.NotConnectedException, XMPPException.XMPPErrorException, SmackException.NoResponseException {
    UserSearchManager search = new UserSearchManager(connection);
    Form searchForm = search
        .getSearchForm("search." + connection.getServiceName());

    Form answerForm = searchForm.createAnswerForm();
    answerForm.setAnswer("Username", true);
    answerForm.setAnswer("search", userName);
    ReportedData data = search
        .getSearchResults(answerForm, "search." + connection.getServiceName());

    if (data.getRows() != null) {
        for (ReportedData.Row row: data.getRows()) {
            for (String value: row.getValues("jid")) {
                Log.i("Iteartor values......", " " + value);
            }
        }

    } else {
        CreateAccount();
    }
}
Paolo Forgia
  • 6,572
  • 8
  • 46
  • 58
Manikandan
  • 131
  • 13

2 Answers2

1

String you are looking for must to be a JID, not an username:

you need something like:

user1@myserver

and not just

user1

Then, it's quite useless in your usecase to check for JID.

MrPk
  • 2,862
  • 2
  • 20
  • 26
  • getting Same Error when I use as user1@myserver... I tried this before call login() method. Because I want to know whether user exist or not... – Manikandan Aug 09 '16 at 04:47
  • As i know it's not possible to perform Jabber Search before a login, I had same problem (auto registration on first login) and had to implement an ugly workaround... tell me if you are interested (however jabber search needs a full jid and not only userid) – MrPk Aug 09 '16 at 07:51
  • Thanks for reply..Yes..after googled I could known that it's not possible to use Search api before login. alternatively I have used this one. [http://stackoverflow.com/questions/6931100/smack-api-user-search/6936698#6936698]..check it out. – Manikandan Aug 10 '16 at 05:03
1

I have register user using below code on smack 4.1:-

   //Login User
   public XMPPTCPConnection loginUser(Context objContext, XMPPTCPConnection objXmpptcpConnection, String strUsername, String strPassword) {

       try {
           AccountManager objAccountManager = AccountManager.getInstance(objXmpptcpConnection);
           objAccountManager.createAccount(strUsername, strPassword);
           objXmpptcpConnection = loginToServer(objXmpptcpConnection, strUsername, strPassword);
       } catch (SmackException | XMPPException e) {

           System.out.println("Msg=" + e.getMessage() + "\nCause =" + e.getCause() + "\n Local msg=" + e.getLocalizedMessage() + "\n stack=" + e.getStackTrace() + "\n class " + e.getClass());
           System.out.println("Code=" + e.getStackTrace()[0].getLineNumber());
           if (e.getMessage().contains("conflict")) {
               objXmpptcpConnection = loginToServer(objXmpptcpConnection, strUsername, strPassword);
           }
       }
       return objXmpptcpConnection;
   }

   private XMPPTCPConnection loginToServer(XMPPTCPConnection objXmpptcpConnection, String strUsername, String strPassword) {

       try {
           objXmpptcpConnection.login(strUsername + "@" + AppConstants.HOST, strPassword, "example");
          // objXmpptcpConnection.sendPacket(new Presence(Presence.Type.unavailable));
//objXmpptcpConnection.sendPacket(new Presence(Presence.Type.available));
       } catch (XMPPException e) {
           e.printStackTrace();
       } catch (SmackException e) {
           e.printStackTrace();
       } catch (IOException e) {
           e.printStackTrace();
       }
       Log.i("XMPPChatDemoActivity", "Logged in as "
               + objXmpptcpConnection.getUser());
       Toast.makeText(
               objContext,
               "log in as "
                       + objXmpptcpConnection.getUser(),
               Toast.LENGTH_SHORT).show();

       return objXmpptcpConnection;
   }

Using above two methods register user to ejabberd successfully.

And Connect Method is:-

public XMPPTCPConnection connect(String strUsername, String strPassword) throws IOException, XMPPException, SmackException {
    objXmpptcpConnection = null;
    if (android.os.Build.VERSION.SDK_INT > 9) {
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
    }
    // Create a connection
    XMPPTCPConnectionConfiguration.Builder config = XMPPTCPConnectionConfiguration.builder();
    config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
    config.setServiceName(Constants.HOST);
    config.setPort(Constants.PORT);
    config.setHost(Constants.HOST);
    config.setDebuggerEnabled(true);
    config.setSendPresence(true);
    config.setUsernameAndPassword(strUsername + "@" + Constants.HOST, strPassword);


    SASLAuthentication.blacklistSASLMechanism("SCRAM-SHA-1");
    SASLAuthentication.blacklistSASLMechanism("DIGEST-MD5");
    SASLAuthentication.unBlacklistSASLMechanism("PLAIN");
    objXmpptcpConnection = new XMPPTCPConnection(config.build());
    objXmpptcpConnection.setUseStreamManagement(true);
    objXmpptcpConnection.setUseStreamManagementResumption(true);
    try {
        ProviderManager objProviderManager = new ProviderManager();
        ProviderManager.addExtensionProvider(DeliveryReceipt.ELEMENT, DeliveryReceipt.NAMESPACE, new DeliveryReceipt.Provider());
        ProviderManager.addExtensionProvider(DeliveryReceiptRequest.ELEMENT, new DeliveryReceiptRequest().getNamespace(), new DeliveryReceiptRequest.Provider());
        ProviderManager.addIQProvider("query", "http://jabber.org/protocol/bytestreams", new BytestreamsProvider());
        ProviderManager.addIQProvider("query", "http://jabber.org/protocol/disco#items", new DiscoverItemsProvider());
        ProviderManager.addIQProvider("query", "http://jabber.org/protocol/disco#info", new DiscoverInfoProvider());

        //  Offline Message Requests
        objProviderManager.addIQProvider("offline", "http://jabber.org/protocol/offline", new OfflineMessageRequest.Provider());

        //  Offline Message Indicator
        objProviderManager.addExtensionProvider("offline", "http://jabber.org/protocol/offline", new OfflineMessageInfo.Provider());
        objXmpptcpConnection.connect();
        System.out.println("Connected to===>" + objXmpptcpConnection.getHost());
        objXmpptcpConnection.login();

        objDeliveryReceiptManager = DeliveryReceiptManager.getInstanceFor(objXmpptcpConnection);
        objDeliveryReceiptManager.autoAddDeliveryReceiptRequests();
        objDeliveryReceiptManager.setAutoReceiptMode(DeliveryReceiptManager.AutoReceiptMode.disabled);
        objDeliveryReceiptManager.addReceiptReceivedListener(this);

    } catch (XMPPException e) {
        e.printStackTrace();
        return objXmpptcpConnection;
    } catch (SmackException e) {
        e.printStackTrace();
        return objXmpptcpConnection;
    } catch (IOException e) {
        e.printStackTrace();
        return objXmpptcpConnection;
    }
    return objXmpptcpConnection;
}

Also you want to check ejabberd side configuration also.

Its working for me tried using the answer :- Smack API User search.

Hope its useful to you.

Community
  • 1
  • 1
Anil Ravsaheb Ghodake
  • 1,587
  • 2
  • 27
  • 45