how to get text of push notification (Urban Airship) - push-notification

I searched my questioin and didn't find the answer. So i'm using urban airship to push notifications and it is working fine. So now i want to make this: when user taps on notification to open the app i want to give him text of notification again in uialertview.
So where i can take the text of notification?
can i do this in this method
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
UIApplicationState appState = UIApplicationStateActive;
if ([application respondsToSelector:#selector(applicationState)]) {
appState = application.applicationState;
}
[[UAPush shared] handleNotification:userInfo applicationState:appState];
[[UAPush shared] resetBadge];}
Thank you very much.

I can read the push notification that opened my app using didReceiveRemoteNotification:(NSDictionary *)userInfo - Here is my didReceiveRemoteNotification:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
// TestFlight API
TESTFLIGHT_CHECKPOINT(#"Receive Remote Notification");
// Urban Airship
[[UAPush shared] handleNotification:userInfo applicationState:application.applicationState];
NSLog(#"userInfo: %#",userInfo);
[UAInboxPushHandler handleNotification:userInfo];
}
When I launch my app from an aps notification I have this in the debug window:
2013-01-17 20:52:49:947 iFlightBag[8229:2311] -[AppDelegate_Shared application:didReceiveRemoteNotification:] [Line 2403] userInfo: {
"_" = "l0-mgGElEeKbHAAbIbyL6A";
aps = {
alert = "Manual: IOM update 2013-01-17T20:14:42-08:00";
badge = 0;
};
operation = update;
tab = manuals;
}

Related

send notification from background worker

am using ABP to build my project
I have a module to generate big size files using background worker, and after each successful file generated I need to send notification, but is not working !
I've put the background job in the core project and the queue in the engine project,
the DB notification tables are updated successfully (new record inserted so the pull notification will work fine !), but the browser doesn't receive the notification (so I can inform him that his file is ready), but there is no errors and no any notification send to the browser.
here is the worker class:
public class GeneratedFileWorker : BackgroundWorkerBase, ISingletonDependency
{
.
.
.
[UnitOfWork]
[AutomaticRetry(Attempts = 0)]
public override async System.Threading.Tasks.Task ExecuteAsync()
{
var notificationData = new NotificationData();
notificationData["URL"] = "app/main/data/generatedfiles";
using (AbpSession.Use(TenantConsts.DefaultTenantId, TenantConsts.UserServiceId))
{
GetDownloadArticleInput getDownloadArticleInput = new GetDownloadArticleInput();
if (pendingRequest is not null)
{
var entityType = _lookupItemManager.Get(pendingRequest.EntityTypeId).Code;
dynamic Args = JsonConvert.DeserializeObject<GetDownloadArticleInput>(String.Empty);
switch (entityType)
{
case "Article":
Args = JsonConvert.DeserializeObject<GetDownloadArticleInput>(pendingRequest.ExtensionData);
break;
case "ArticlesList":
Args = JsonConvert.DeserializeObject<GetDownloadArticlesInput>(pendingRequest.ExtensionData);
break;
};
GeneratedFile generatedFileDto = new GeneratedFile();
try
{
generatedFileDto = await _generateFile.Generate(Args);
await _appNotifier.SendMessageAsync(new UserIdentifier(1, pendingRequest.CreatorUserId.Value),string.Format(_LocalizationSource.GetString("GeneratedFile.fileIsNotready"), _lookupItemManager.GetTitle(pendingRequest.EntityTypeId)), notificationData, NotificationSeverity.Error);
else
await _appNotifier.SendMessageAsync(new UserIdentifier(1, pendingRequest.CreatorUserId.Value), string.Format(_LocalizationSource.GetString("GeneratedFile.fileIsready"), _lookupItemManager.GetTitle(pendingRequest.EntityTypeId)), notificationData, NotificationSeverity.Success);
}
catch (Exception ex)
{
pendingRequest.CurrentStateId = _lookupItemManager.GetByCode(LookupCategories.GeneratedFileStatus, "Failed").Id;
pendingRequest.OperationResult = ex.ToString();
await _generatedFileRepository.UpdateAsync(pendingRequest);
await _appNotifier.SendMessageAsync(new UserIdentifier(1, pendingRequest.CreatorUserId.Value), string.Format(_LocalizationSource.GetString("GeneratedFile.fileIsNotready"), _lookupItemManager.GetTitle(pendingRequest.EntityTypeId)), notificationData, NotificationSeverity.Error);
}
}
}
}
I have 2 cases here:
first one working when I define the queue in the host project, and
second one not working when I define the queue in the engine project

How to inject the Firebase messaging isHeadless prop into AppDelegate.mm file with react-native 0.69.1

System Information:
System:
OS: macOS 12.4
CPU: (8) arm64 Apple M1
Memory: 97.44 MB / 8.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 16.16.0 - /opt/homebrew/opt/node#16/bin/node
Yarn: 1.22.19 - /opt/homebrew/bin/yarn
npm: 8.11.0 - /opt/homebrew/opt/node#16/bin/npm
Watchman: 2022.07.04.00 - /opt/homebrew/bin/watchman
Managers:
CocoaPods: 1.11.3 - /opt/homebrew/bin/pod
SDKs:
iOS SDK:
Platforms: DriverKit 21.4, iOS 15.5, macOS 12.3, tvOS 15.4, watchOS 8.5
Android SDK: Not Found
IDEs:
Android Studio: 2020.3 AI-203.7717.56.2031.7583922
Xcode: 13.4.1/13F100 - /usr/bin/xcodebuild
Languages:
Java: 11.0.15 - /usr/bin/javac
npmPackages:
#react-native-community/cli: Not Found
react: 18.0.0 => 18.0.0
react-native: 0.69.1 => 0.69.1
react-native-macos: Not Found
npmGlobalPackages:
*react-native*: Not Found
Hello folks, I am working on a react-native 0.69.1 project that uses Firebase push-notification service. I confirm that I am successfully getting push notifications when the app is in the foreground, background and in a killed state. In order to correctly update my badge count when receiving a push notification outside the app, I need to add to index.js the firebase method setBackgroundMessageHandler and handle if the app was opened via isHeadless prop.
import {AppRegistry} from 'react-native';
import App from './src/App';
import {name as appName} from './app.json';
import messaging from '#react-native-firebase/messaging';
// Register background handler
messaging().setBackgroundMessageHandler(async remoteMessage => {
//Update badge count in here
});
function HeadlessCheck({isHeadless}) {
if (isHeadless) {
// App has been launched in the background by iOS, ignore
return null;
}
return App;
}
AppRegistry.registerComponent(appName, () => HeadlessCheck);
I am aware that the headless prop does not exist on iOS and needs to be injected into AppDelegate.m/AppDelegate.mm file. However firebase has not updated their documentation to inject the isHeadless prop into the AppDelegate.mm file created by react-native-0.69.1.
Below is the snipped of my AppDelegate.mm file where I have to inject the isHeadless prop in.
#import "AppDelegate.h"
#import "RNBootSplash.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RCTAppSetupUtils.h>
#import <UserNotifications/UserNotifications.h>
#import <RNCPushNotificationIOS.h>
#import <Firebase.h>
#import <TSBackgroundFetch/TSBackgroundFetch.h>
#if RCT_NEW_ARCH_ENABLED
#import <React/CoreModulesPlugins.h>
#import <React/RCTCxxBridgeDelegate.h>
#import <React/RCTFabricSurfaceHostingProxyRootView.h>
#import <React/RCTSurfacePresenter.h>
#import <React/RCTSurfacePresenterBridgeAdapter.h>
#import <ReactCommon/RCTTurboModuleManager.h>
#import <react/config/ReactNativeConfig.h>
static NSString *const kRNConcurrentRoot = #"concurrentRoot";
#interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
RCTTurboModuleManager *_turboModuleManager;
RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
facebook::react::ContextContainer::Shared _contextContainer;
}
#end
#endif
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FIRApp configure];
RCTAppSetupPrepareApp(application);
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
#if RCT_NEW_ARCH_ENABLED
_contextContainer = std::make_shared<facebook::react::ContextContainer const>();
_reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
_contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
_bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer];
bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
#endif
NSDictionary *initProps = [self prepareInitialProps];
UIView *rootView = RCTAppSetupDefaultRootView(bridge, #"amigo", initProps);
if (#available(iOS 13.0, *)) {
rootView.backgroundColor = [UIColor systemBackgroundColor];
} else {
rootView.backgroundColor = [UIColor whiteColor];
}
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
// Define UNUserNotificationCenter
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
// [REQUIRED] Register BackgroundFetch
[[TSBackgroundFetch sharedInstance] didFinishLaunching];
[RNBootSplash initWithStoryboard:#"BootSplash" rootView:rootView];
return YES;
}
//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge);
}
// Required for the register event.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
[RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
// Required for the notification event. You must call the completion handler after handling the remote notification.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
[RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
// Required for the registrationError event.
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
[RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
}
// Required for localNotification event
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)(void))completionHandler
{
[RNCPushNotificationIOS didReceiveNotificationResponse:response];
}
/// This method controls whether the `concurrentRoot`feature of React18 is turned on or off.
///
/// #see: https://reactjs.org/blog/2022/03/29/react-v18.html
/// #note: This requires to be rendering on Fabric (i.e. on the New Architecture).
/// #return: `true` if the `concurrentRoot` feture is enabled. Otherwise, it returns `false`.
- (BOOL)concurrentRootEnabled
{
// Switch this bool to turn on and off the concurrent root
return true;
}
- (NSDictionary *)prepareInitialProps
{
NSMutableDictionary *initProps = [NSMutableDictionary new];
#ifdef RCT_NEW_ARCH_ENABLED
initProps[kRNConcurrentRoot] = #([self concurrentRootEnabled]);
#endif
return initProps;
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:#"index"];
#else
return [[NSBundle mainBundle] URLForResource:#"main" withExtension:#"jsbundle"];
#endif
}
#if RCT_NEW_ARCH_ENABLED
#pragma mark - RCTCxxBridgeDelegate
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
{
_turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
delegate:self
jsInvoker:bridge.jsCallInvoker];
return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager);
}
#pragma mark RCTTurboModuleManagerDelegate
- (Class)getModuleClassFromName:(const char *)name
{
return RCTCoreModulesClassProvider(name);
}
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
{
return nullptr;
}
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
initParams:
(const facebook::react::ObjCTurboModule::InitParams &)params
{
return nullptr;
}
- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
{
return RCTAppSetupDefaultModuleFromClass(moduleClass);
}
#endif
#end
RN Community , please help me out if you experience the same issue :)
You can change this
UIView *rootView = RCTAppSetupDefaultRootView(bridge, #"amigo", initProps);
to
NSDictionary *appProperties = [RNFBMessagingModule addCustomPropsToUserProps:nil withLaunchOptions:launchOptions];
NSMutableDictionary *initialProps = [initProps mutableCopy];
[initialProps addEntriesFromDictionary:appProperties];
UIView *rootView = RCTAppSetupDefaultRootView(bridge, #"amigo", initialProps);

WKExtensionsDelegateClassName is Invalid in info.plist

So I am banging my head, I realized my stand along Watch App had a STUPID long name of "App Name - WatchKit App" so I went into my Target and changed the Display Name to "App Name" removing WatchKit App. Well now my app won't validate when uploading to the Appstore. I get the message - Invalid Info.plist key. The key WKExtensionDelegateClassName in bundle App Name.app/Watch/App Name WatchKit App.app is invalid.
My Info.plist has the value of
<key>WKExtensionDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).ExtensionDelegate</string>
I have confirmed that I have #WKExtensionDelegateAdaptor(ExtensionDelegate.self) var delegate in my #main for the SwiftUI App. And when I print a few values in my app launch I get the following confirmations:
Super Init - ExtensionDelegate
Contentview
applicationDidFinishLaunching for watchOS
Super Init - ExtensionDelegate
Optional(Wasted_Time_Watch_Extension.MeetingSetup)
Optional(Wasted_Time_Watch_Extension.MeetingStatistics)
Optional(Wasted_Time_Watch_Extension.Meeting)
applicationDidBecomeActive for watchOS
update complication
I create three classes at launch and print this in the log with print(ExtensionDelegate.shared.Setup as Any) , etc. The other lines are just confirming where I am at app startup.
This is a WatchOS8 application and I am running Xcode version Version 13.1 (13A1030d).
Update - Here's the entry in my plist
<key>WKExtensionDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).ExtensionDelegate</string>
<key>WKWatchOnly</key>
And my App code
import SwiftUI
#if os(watchOS)
import ClockKit
#endif
struct DelegateKey: EnvironmentKey {
typealias Value = ExtensionDelegate
static let defaultValue: ExtensionDelegate = ExtensionDelegate()
}
extension EnvironmentValues {
var extensionDelegate: DelegateKey.Value {
get {
return self[DelegateKey.self]
}
set {
self[DelegateKey.self] = newValue
}
}
}
#main
struct WastedTimeWatchApp: App {
#WKExtensionDelegateAdaptor(ExtensionDelegate.self) var delegate
let prefs: UserDefaults = UserDefaults(suiteName: suiteName)!
#SceneBuilder var body: some Scene {
WindowGroup {
NavigationView {
ContentView()
.environment(\.extensionDelegate, delegate)
}
}
}
}
class ExtensionDelegate: NSObject, WKExtensionDelegate, ObservableObject {
#Environment(\.extensionDelegate) static var shared
// variables removed to simplify posting
override init() {
print("Super Init - ExtensionDelegate")
super.init()
}
func applicationDidFinishLaunching() {
print("applicationDidFinishLaunching for watchOS")
ExtensionDelegate.shared.meetingSetup = MeetingSetup()
print(ExtensionDelegate.shared.meetingSetup as Any)
ExtensionDelegate.shared.meetingStatistics = MeetingStatistics()
print(ExtensionDelegate.shared.meetingStatistics as Any)
ExtensionDelegate.shared.meeting = Meeting()
print(ExtensionDelegate.shared.meeting as Any)
}
func applicationDidBecomeActive() {
print("applicationDidBecomeActive for watchOS")
print("update complication")
let server = CLKComplicationServer.sharedInstance()
for complication in server.activeComplications ?? [] {
server.reloadTimeline(for: complication)
}
}
func applicationDidBecomeInactive() {
print("update complication")
let server = CLKComplicationServer.sharedInstance()
for complication in server.activeComplications ?? [] {
server.reloadTimeline(for: complication)
}
print("applicationDidBecomeInactive for watchOS")
}
}
I figured this out... I had duplicated the plist entry in both the WatchKit App and WatchKit Extension plist file. Removed it from the list WatchKit Extension plist and all is working fine.

Custome notification sound is playing only if i have breakpoint windows universal 8.1

Hi when push notification is received i am displaying toast notification. i have issue that is if i have break point in below function then and then only custom notification sound is playing else notification sound is not playing.I thought might be audio is not loading so i added Task.delay for 2 sec/5 sec but no luck. What could be the issue..
public static void AddTostNotification(String xmlDocument)
{
List<string> messageSection = PushNotificationHelper.GetMessageAndLandingPage(xmlDocument);
ToastTemplateType toastTemplate = ToastTemplateType.ToastText01;
XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(toastTemplate);
XmlNodeList toastTextElements = toastXml.GetElementsByTagName("text");
toastTextElements[0].AppendChild(toastXml.CreateTextNode(messageSection[0]));
// toastTextElements[1].AppendChild(toastXml.CreateTextNode(message));
IXmlNode toastNode = toastXml.SelectSingleNode("/toast");
((XmlElement)toastNode).SetAttribute("launch", messageSection[1]);
XmlElement audio = toastXml.CreateElement("audio");
audio.SetAttribute("src", "ms-appx:///Assets/Guitar.wav");
toastNode.AppendChild(audio);
//launch tost immediatly
ToastNotification toast = new ToastNotification(toastXml);
ToastNotificationManager.CreateToastNotifier().Show(toast);
}
i got it, It was threading issue,
//var ignored = dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
//{
PushNotificationHelper.AddTostNotification(notificationContent);
//});

Enter in my application when i click on the notification in the notifications bar

In my application the user can decide if show the notifications or not through a preferences screen. Well the notification works but i would that clicking on the notification i would be able to enter in my application. This is my code:
#SuppressLint("NewApi")
private void checkPref(Intent intent){
this.registerReceiver(this.batteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
SharedPreferences myPref = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
boolean pref_opt1 = myPref.getBoolean("firstDependent", false);
int level= intent.getIntExtra(BatteryManager.EXTRA_LEVEL,-1);
if (pref_opt1){
NotificationManager notifi = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification.Builder(getApplicationContext())
.setContentTitle("Battery Informations")
.setContentText("Battery level"+" "+level+"%")
.setSmallIcon(R.drawable.icon_small_not)
//.setLargeIcon(aBitmap)
.setTicker(level+"%")
.build();
notification.flags = Notification.FLAG_ONGOING_EVENT;
Intent i = new Intent(MainActivity.this, MainActivity.class);
PendingIntent penInt = PendingIntent.getActivity(getApplicationContext(), 0 , i , 0);
notifi.notify(215,notification);
} else {
NotificationManager notifi = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notifi.cancel(215);
}
}
I thought the PendingIntent did this function but nothing happen. How can i do it?
You need to add the pending intent to the Notification using setContentIntent().
See also the documentation for Notification.contentIntent; in particular note that you'll need FLAG_ACTIVITY_NEW_TASK on the Intent, and also make sure that your MainActivity is declared in AndroidManifest.xml so the notification manager (actually, the System UI) can see it.

Resources