quickblox-android-sdk: Problems when subscribing to push notifications. (SubscribeService)
Environment details
- Any Android API
- Any Quickblox SDK (Currently 3.3.5)
Did this work before?
- No, this is happening regularly every release.
Expected behavior
- The app should not crash when subscribing to push notifications
Actual behavior
- The app crashes when subscribing to push notifications
Logs
Steps to reproduce the behavior
- I was unable to reproduce the problem no matter which android version/quickblox sdk version for Decorators and ToStringHelper and Quickblox core
- SubscribeService.subscibeToPushes(…) crashes on Android O devices.
Quickblox Usage in app
Project structure:
- messaging package contains the abstraction of instant messaging in our app.
- quickblox package is the Quickblox implementation of the instant messaging.
- InstantMessaging is the main class. You can call any of the other interfaces from within this class:
MessagesDispatcher getMessagesDispatcher();
DialogsReceiver getDialogsReceiver();
NotificationsDispatcher getNotificationsDispatcher();
Authenticator getAuthenticator();
ConnectionManager getConnectionManager();
- There’s only one instance of InstantMessaging and it’s a field in the Application class.
Initializing quickblox
- Calling this onCreate of Application, if the user is logged in to the app:
public void initialiseInstantMessaging(final EmptyCallback callback) {
instantMessaging = new QuickBloxInstantMessaging(this);
try {
instantMessaging.initialize(new EmptyCallback() {
@Override
public void onSuccess() {
callback.onSuccess();
}
@Override
public void onFailure() {
}
});
} catch (Exception e) {
Log.d(TAG, e.toString());
}
}
-> InstantMessagin.initialize excecutes this task:
/**
* Initialization task. It's done in an {@link AsyncTask because, by default, the
* Quickblox initialization is done on the UI thread. Blocking UI until it's finished.
*/
private class initTask extends AsyncTask<EmptyCallback, Void, EmptyCallback> {
@Override
protected EmptyCallback doInBackground(EmptyCallback... params) {
authenticateApi();
initApi();
return params[0];
}
@Override
protected void onPostExecute(final EmptyCallback callback) {
super.onPostExecute(callback);
quickbloxConnectionManager.addConnectionListener();
updateChatEnabled();
quickbloxAuthenticator.login(credentials.getUsername(), credentials.getPassword(), new EmptyCallback() {
@Override
public void onSuccess() {
callback.onSuccess();
}
@Override
public void onFailure() {
reconnectApi(new EmptyCallback() {
@Override
public void onSuccess() {
callback.onSuccess();
}
@Override
public void onFailure() {
}
});
}
});
}
}
-> authenticateApi() :
/**
* Authenticates {@link QuickBloxInstantMessaging with the appropriate
* credentials depending on current product flavor.
*/
@Override
public void authenticateApi() {
if (!BuildConfig.DEBUG_ENABLED) {
QBSettings.getInstance().setStoringMehanism(StoringMechanism.UNSECURED);
QBSettings.getInstance().setEndpoints(API_DOMAIN, CHAT_DOMAIN, ServiceZone.PRODUCTION);
QBSettings.getInstance().init(context, APP_ID, AUTH_KEY, AUTH_SECRET);
QBSettings.getInstance().setAccountKey(ACCOUNT_KEY);
QBSettings.getInstance().setEnablePushNotification(true);
QBSettings.getInstance().setSubscribePushStrategy(SubscribePushStrategy.ALWAYS);
} else {
QBSettings.getInstance().setStoringMehanism(StoringMechanism.UNSECURED);
QBSettings.getInstance().setEndpoints(API_DOMAIN, CHAT_DOMAIN, ServiceZone.PRODUCTION);
QBSettings.getInstance().init(context, DEV_APP_ID, DEV_AUTH_KEY, DEV_AUTH_SECRET);
QBSettings.getInstance().setAccountKey(DEV_ACCOUNT_KEY);
QBSettings.getInstance().setEnablePushNotification(true);
QBSettings.getInstance().setSubscribePushStrategy(SubscribePushStrategy.ALWAYS);
}
}
-> initApi():
/**
* Initializes the APIs configurations.
*/
@Override
public void initApi() {
QBChatService.setDebugEnabled(true);
QBChatService.setDefaultAutoSendPresenceInterval(15);
QBChatService.ConfigurationBuilder builder = new QBChatService.ConfigurationBuilder();
builder.setAutojoinEnabled(true);
builder.setSocketTimeout(200);
builder.setKeepAlive(true);
builder.setReconnectionAllowed(true);
builder.setUseTls(true);
QBChatService.setConfigurationBuilder(builder);
}
Using the InstantMessaging instance:
- From the Application class:
public InstantMessaging getInstantMessagingApi() throws NotLoggedInException {
if (instantMessaging == null || !instantMessaging.getAuthenticator().isLoggedIn()) {
throw new NotLoggedInException("User isn't logged in, can't init Instant Messaging");
}
return instantMessaging;
}
Subscribing to pushes
- When the user successfully logs in to quickblox, the QuickbloxConnectionManager subscribes to push notifications.
/**
* Authenticates the current user with Quickblox and logs in.
*/
@Override
public void login(String username, String password, final EmptyCallback callback) {
final QBUser qUser = new QBUser(username, Base64Helper.encode(password));
QBAuth.createSession(qUser).performAsync(new QBEntityCallback<QBSession>() {
@Override
public void onSuccess(QBSession qbSession, Bundle bundle) {
qUser.setId(qbSession.getUserId());
QBChatService.getInstance().login(qUser, new QBEntityCallback() {
@Override
public void onSuccess(Object o, Bundle bundle) {
getInstantMessaging().getConnectionManager().initManagersListeners();
getInstantMessaging().getConnectionManager().subscribeToPushNotifications();
/// code..
-> Subscribe to push notifications::
/**
* Subscribes the user to offline push notifications.
*/
@Override
public void subscribeToPushNotifications() {
try {
if (getInstantMessaging().getAuthenticator().isLoggedIn()) {
SubscribeService.subscribeToPushes(context, true);
QBPushManager.getInstance().addListener(new QBPushManager.QBSubscribeListener() {
@Override
public void onSubscriptionCreated() {
Log.d(TAG, "Subscribed to push notifications");
}
@Override
public void onSubscriptionError(Exception e, int i) {
Log.d(TAG, "Failed to subscribe to push notifications: " + e.toString());
}
@Override
public void onSubscriptionDeleted(boolean b) {
Log.d(TAG, "Subscription deleted to push notifications");
}
});
}
} catch (Exception e) {
Log.d(TAG, e.toString());
}
}
-> Check if the user is logged in:
/**
* Checks if the current user is logged in.
*
* @return true if the user is logged in.
*/
@Override
public boolean isLoggedIn() {
try {
return QBChatService.getInstance() != null && QBChatService.getInstance().isLoggedIn();
} catch (Exception e) {
return false;
}
}
Android Oreo problems
- Calling
startService()throws anIllegalStateExceptionon Android Oreo devices. - Quickblox calls this method when
SubscribeService.subscribeToPushes(..)is called:
Intent intent = new Intent(context, SubscribeService.class);
intent.putExtra("extraSubscribe", true);
context.startService(intent);
EDIT:
- Small note, the README in quickblox android releases github says 3.4.0 however 3.4.0 doesn’t compile but 3.4 does.
- Added a new crash stack trace that happened just recently.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 18 (7 by maintainers)
I am also facing the same issue where my targeted version of the app is Android API level 28. I’m using Quick Blox SDK version 3.8.1.
Does anyone found any solution?