push notification in ionic3 using phonegap push plugin - firebase

I am new to ionic 3 and I have implemented phonegap push notification on an app I am building and I am not getting any kind of notification, not even alert message which should show when the app is registered, so can someone provide me with some help for this issue.
Thanks beforehand.
app.component.ts
import { Component, ViewChild } from '#angular/core';
import { Platform, Nav, Icon,AlertController} from 'ionic-angular';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import firebase from 'firebase';
import { EventlistPage } from '../pages/eventlist/eventlist';
import { SigninPage } from '../pages/signin/signin';
import { SignupPage } from '../pages/signup/signup';
import { settingsPage } from '../pages/settings/settings';
import { NewsPage } from '../pages/news/news';
// import { AddeventPage } from '../pages/addevent/addevent';
// import {EventdetailsPage} from '../pages/eventdetails/eventdetails';
import { ProfilePage } from '../pages/profile/profile';
import {AuthService} from '../services/auth'
import { ENV } from '../environments/environment.dev';
import { Push, PushObject, PushOptions } from '#ionic-native/push';
#Component({
templateUrl: 'app.html'
})
export class MyApp {
#ViewChild (Nav) nav: Nav; //can't inject nav controller in the constructor in the root component
rootPage:any = EventlistPage;
eventsListPage=EventlistPage;
signinPage = SigninPage;
signupPage = SignupPage;
isAuthenticated = false;
show: boolean = false;
pages: Array<{title: string, component: any,icon:string}>;
constructor(
private authService:AuthService,
public platform: Platform,
statusBar: StatusBar,
splashScreen: SplashScreen,
private push: Push,
public alertCtrl: AlertController) {
firebase.initializeApp(ENV);
firebase.auth().onAuthStateChanged(user => {
if (user) {
this.isAuthenticated = true;
this.rootPage=EventlistPage;//as firebase checks the user state asynchronously before the nav gets initialized
this.show = true;
} else {
this.isAuthenticated = false;
this.rootPage=SigninPage;
}
if(!this.isAuthenticated){
//this.rootPage=SigninPage;
this.pages = [
{ title: 'SignIn', component: SigninPage , icon: "log-in"},
{ title: 'Register', component: SignupPage, icon: "book"}
];
}else{
this.pages = [
{ title: 'news', component: NewsPage, icon: "paper"},
{ title: 'events', component: EventlistPage, icon: "albums" },
{ title: 'profile', component: ProfilePage , icon: "person"},
{ title: 'settings', component: settingsPage, icon: "settings"}
];
}
});
// platform.ready().then(() => {
// // Okay, so the platform is ready and our plugins are available.
// // Here you can do any higher level native things you might need.
// statusBar.styleDefault();
// splashScreen.hide();
// });
platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
this.pushsetup();
statusBar.styleDefault();
if (platform.is('android')) {
statusBar.overlaysWebView(false);
statusBar.backgroundColorByHexString('#000000');
}
splashScreen.hide();
});
}
onLogOut(){
this.authService.logOut();
this.show = false;
}
openPage(page) {
// Reset the content nav to have just this page
// we wouldn't want the back button to show in this scenario
this.rootPage=page.component
//this.nav.setRoot(page.Component);
}
pushsetup() {
if (!this.platform.is('cordova')) {
console.warn('Push notifications not initialized. Cordova is not available - Run in physical device');
return;
}
const options: PushOptions = {
android: {
senderID: '333057397510'
},
ios: {
alert: 'true',
badge: false,
sound: 'true'
},
windows: {}
};
const pushObject: PushObject = this.push.init(options);
pushObject.on('registration').subscribe((data: any) => {
alert('device token -> ' + data.registrationId);
//TODO - send device token to server
});
pushObject.on('notification').subscribe((data: any) => {
console.log('message -> ' + data.message);
//if user using app and push notification comes
if (data.additionalData.foreground) {
// if application open, show popup
let confirmAlert = this.alertCtrl.create({
title: 'New Notification',
message: data.message,
buttons: [{
text: 'Ignore',
role: 'cancel'
}, {
text: 'View',
handler: () => {
//TODO: Your logic here
this.nav.push(EventlistPage, { message: data.message });
}
}]
});
confirmAlert.present();
} else {
//if user NOT using app and push notification comes
//TODO: Your logic on click of push notification directly
this.nav.push(EventlistPage, { message: data.message });
console.log('Push notification clicked');
}
});
pushObject.on('error').subscribe(error => console.error('Error with Push plugin' + error));
}
}
config.xml
<?xml version='1.0' encoding='utf-8'?>
<widget id="dfd.dfd.dfd" version="0.0.3" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>hghg</name>
<description>An awesome Ionic/Cordova app.</description>
<author email="hi#ionicframework" href="http://ionicframework.com/">Ionic Framework Team</author>
<content src="index.html" />
<access origin="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<preference name="ScrollEnabled" value="false" />
<preference name="android-minSdkVersion" value="19" />
<preference name="BackupWebStorage" value="none" />
<preference name="SplashMaintainAspectRatio" value="true" />
<preference name="FadeSplashScreenDuration" value="300" />
<preference name="SplashShowOnlyFirstTime" value="false" />
<preference name="SplashScreen" value="screen" />
<preference name="SplashScreenDelay" value="3000" />
<platform name="android">
<allow-intent href="market:*" />
<icon density="ldpi" src="resources/android/icon/drawable-ldpi-icon.png" />
<icon density="mdpi" src="resources/android/icon/drawable-mdpi-icon.png" />
<icon density="hdpi" src="resources/android/icon/drawable-hdpi-icon.png" />
<icon density="xhdpi" src="resources/android/icon/drawable-xhdpi-icon.png" />
<icon density="xxhdpi" src="resources/android/icon/drawable-xxhdpi-icon.png" />
<icon density="xxxhdpi" src="resources/android/icon/drawable-xxxhdpi-icon.png" />
<splash density="land-ldpi" src="resources/android/splash/drawable-land-ldpi-screen.png" />
<splash density="land-mdpi" src="resources/android/splash/drawable-land-mdpi-screen.png" />
<splash density="land-hdpi" src="resources/android/splash/drawable-land-hdpi-screen.png" />
<splash density="land-xhdpi" src="resources/android/splash/drawable-land-xhdpi-screen.png" />
<splash density="land-xxhdpi" src="resources/android/splash/drawable-land-xxhdpi-screen.png" />
<splash density="land-xxxhdpi" src="resources/android/splash/drawable-land-xxxhdpi-screen.png" />
<splash density="port-ldpi" src="resources/android/splash/drawable-port-ldpi-screen.png" />
<splash density="port-mdpi" src="resources/android/splash/drawable-port-mdpi-screen.png" />
<splash density="port-hdpi" src="resources/android/splash/drawable-port-hdpi-screen.png" />
<splash density="port-xhdpi" src="resources/android/splash/drawable-port-xhdpi-screen.png" />
<splash density="port-xxhdpi" src="resources/android/splash/drawable-port-xxhdpi-screen.png" />
<splash density="port-xxxhdpi" src="resources/android/splash/drawable-port-xxxhdpi-screen.png" />
<resource-file src="google-services.json" target="app/google-services.json" />
<resource-file src="google-services.json" target="google-services.json" />
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
<icon height="57" src="resources/ios/icon/icon.png" width="57" />
<icon height="114" src="resources/ios/icon/icon#2x.png" width="114" />
<icon height="40" src="resources/ios/icon/icon-40.png" width="40" />
<icon height="80" src="resources/ios/icon/icon-40#2x.png" width="80" />
<icon height="120" src="resources/ios/icon/icon-40#3x.png" width="120" />
<icon height="50" src="resources/ios/icon/icon-50.png" width="50" />
<icon height="100" src="resources/ios/icon/icon-50#2x.png" width="100" />
<icon height="60" src="resources/ios/icon/icon-60.png" width="60" />
<icon height="120" src="resources/ios/icon/icon-60#2x.png" width="120" />
<icon height="180" src="resources/ios/icon/icon-60#3x.png" width="180" />
<icon height="72" src="resources/ios/icon/icon-72.png" width="72" />
<icon height="144" src="resources/ios/icon/icon-72#2x.png" width="144" />
<icon height="76" src="resources/ios/icon/icon-76.png" width="76" />
<icon height="152" src="resources/ios/icon/icon-76#2x.png" width="152" />
<icon height="167" src="resources/ios/icon/icon-83.5#2x.png" width="167" />
<icon height="29" src="resources/ios/icon/icon-small.png" width="29" />
<icon height="58" src="resources/ios/icon/icon-small#2x.png" width="58" />
<icon height="87" src="resources/ios/icon/icon-small#3x.png" width="87" />
<icon height="1024" src="resources/ios/icon/icon-1024.png" width="1024" />
<splash height="1136" src="resources/ios/splash/Default-568h#2x~iphone.png" width="640" />
<splash height="1334" src="resources/ios/splash/Default-667h.png" width="750" />
<splash height="2208" src="resources/ios/splash/Default-736h.png" width="1242" />
<splash height="1242" src="resources/ios/splash/Default-Landscape-736h.png" width="2208" />
<splash height="1536" src="resources/ios/splash/Default-Landscape#2x~ipad.png" width="2048" />
<splash height="2048" src="resources/ios/splash/Default-Landscape#~ipadpro.png" width="2732" />
<splash height="768" src="resources/ios/splash/Default-Landscape~ipad.png" width="1024" />
<splash height="2048" src="resources/ios/splash/Default-Portrait#2x~ipad.png" width="1536" />
<splash height="2732" src="resources/ios/splash/Default-Portrait#~ipadpro.png" width="2048" />
<splash height="1024" src="resources/ios/splash/Default-Portrait~ipad.png" width="768" />
<splash height="960" src="resources/ios/splash/Default#2x~iphone.png" width="640" />
<splash height="480" src="resources/ios/splash/Default~iphone.png" width="320" />
<splash height="2732" src="resources/ios/splash/Default#2x~universal~anyany.png" width="2732" />
</platform>
<plugin name="cordova-plugin-whitelist" spec="1.3.3" />
<plugin name="cordova-plugin-statusbar" spec="2.4.2" />
<plugin name="cordova-plugin-device" spec="2.0.2" />
<plugin name="cordova-plugin-splashscreen" spec="5.0.2" />
<plugin name="cordova-plugin-ionic-webview" spec="^2.0.0" />
<plugin name="cordova-plugin-ionic-keyboard" spec="^2.0.5" />
<plugin name="cordova-plugin-file" spec="^6.0.1" />
<plugin name="cordova-plugin-filechooser" spec="^1.0.1" />
<plugin name="cordova-plugin-filepath" spec="^1.4.2" />
<plugin name="phonegap-plugin-push" spec="^2.2.3">
<variable name="SENDER_ID" value="jjhgjgjhgjhgj" />
</plugin>
<engine name="android" spec="7.0.0" />
</widget>
package.json
{
"name": "events",
"version": "0.0.1",
"author": "Ionic Framework",
"homepage": "http://ionicframework.com/",
"private": true,
"config": {
"ionic_webpack": "./config/webpack.config.js"
},
"scripts": {
"start": "ionic-app-scripts serve",
"clean": "ionic-app-scripts clean",
"build": "ionic-app-scripts build",
"lint": "ionic-app-scripts lint"
},
"dependencies": {
"#angular/animations": "5.2.11",
"#angular/common": "5.2.11",
"#angular/compiler": "5.2.11",
"#angular/compiler-cli": "5.2.11",
"#angular/core": "5.2.11",
"#angular/forms": "5.2.11",
"#angular/http": "5.2.11",
"#angular/platform-browser": "5.2.11",
"#angular/platform-browser-dynamic": "5.2.11",
"#ionic-native/core": "^4.12.2",
"#ionic-native/file": "^4.15.0",
"#ionic-native/file-chooser": "^4.15.0",
"#ionic-native/file-path": "^4.15.0",
"#ionic-native/push": "^4.16.0",
"#ionic-native/splash-screen": "~4.12.0",
"#ionic-native/status-bar": "~4.12.0",
"#ionic/storage": "2.1.3",
"angularfire2": "^5.0.2",
"cordova-android": "7.0.0",
"cordova-plugin-device": "^2.0.2",
"cordova-plugin-file": "^6.0.1",
"cordova-plugin-filechooser": "^1.0.1",
"cordova-plugin-filepath": "^1.4.2",
"cordova-plugin-ionic-keyboard": "^2.1.3",
"cordova-plugin-ionic-webview": "^2.2.0",
"cordova-plugin-splashscreen": "^5.0.2",
"cordova-plugin-statusbar": "^2.4.2",
"cordova-plugin-whitelist": "^1.3.3",
"firebase": "^5.5.3",
"ionic-angular": "3.9.2",
"ionicons": "3.0.0",
"ngx-show-hide-password": "^1.2.6",
"phonegap-plugin-push": "^2.2.3",
"rxjs": "^6.0.0",
"rxjs-compat": "^6.3.2",
"sw-toolbox": "3.6.0",
"zone.js": "0.8.26"
},
"devDependencies": {
"#ionic/app-scripts": "3.2.0",
"#ionic/lab": "1.0.11",
"typescript": "~2.6.2"
},
"description": "An Ionic project",
"cordova": {
"plugins": {
"cordova-plugin-whitelist": {},
"cordova-plugin-statusbar": {},
"cordova-plugin-device": {},
"cordova-plugin-splashscreen": {},
"cordova-plugin-ionic-webview": {
"ANDROID_SUPPORT_ANNOTATIONS_VERSION": "27.+"
},
"cordova-plugin-ionic-keyboard": {},
"cordova-plugin-filechooser": {},
"cordova-plugin-file": {},
"cordova-plugin-filepath": {},
"phonegap-plugin-push": {
"SENDER_ID": "ghghfhgfh"
}
},
"platforms": [
"android"
]
}
}

have you configured your file google-services.json in the root of the project? In case you are building for IOS you have to configure the GoogleService-info.plist and the proper certificates on your account

Well, I got the answer from phonegap plugin's issue page in github.
I removed android 7.0.0 and added 7.1.0
Then edited gradle files by rearranging maven and jcenter in the project.

Related

why getServerSideProps(SSR) doesn't work at vercel deploy

I am trying to deploying next js instagram clone coding.
so i used the getServerSideProps for singin with google.
it works at localhost:3000 what i want.
but after deploying this web then when i click the signin then turns out server error page.
i don't know what can i do to solve this problem.
i already downgrade firbase to 9.4.0
and i used getStaticProps(?) instead of getServerSideProps..
(if i need to use useeffect instead of getServerSideProps then please show me detail code please.... i am beginner :( )
please help me out
this is signIn code:
import {getProviders, signIn as SignIntoProvider } from "next-auth/react";
import Header from "../../components/Header";
import Image from "next/future/image";
//Brower...
function signIn({providers}){
return (
<>
<Header />
<div className="flex flex-col items-center min-h-screen py-2 mt-56 text-center">
<Image className="w-80" src="/img/스쿼드 로고.png" alt="" width={400} height={200}/>
<p className="font-xs italic">
SQUARD PROJECT - By EunSeo PARK
</p>
<div className='mt-20'>
{Object.values(providers).map((provider) => (
<div key={provider.name}>
<button className="p-3 bg-blue-500 rounded-lg text-white" onClick={() => SignIntoProvider(provider.id, {callbackUrl: "/"})}>
Sign in with {provider.name}
</button>
</div>
))}
</div>
</div>
</>
);
}
//Server side
//export async function getServerSidedProps
export async function getServerSideProps() {
const providers = await getProviders();
if (!providers) {
return {
redirect: {
destination: '/',
permanent: false,
},
}
}
return {
props: {
providers,
},
};
}
export default signIn;
this is the package.json code:
{
"name": "my-project",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"#faker-js/faker": "^7.5.0",
"#headlessui/react": "^1.7.2",
"#heroicons/react": "^1.0.6",
"#tailwindcss/forms": "^0.5.3",
"fake": "^0.2.2",
"faker": "^6.6.6",
"firebase": "^9.4.0",
"moment": "^2.29.4",
"next": "12.3.0",
"next-auth": "^4.10.3",
"next-optimized-images": "^2.6.2",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-moment": "^1.1.2",
"react-router-dom": "^6.4.1",
"recoil": "^0.7.5",
"tailwind-scrollbar-hide": "^1.1.7",
"typescript": "^4.8.4"
},
"devDependencies": {
"autoprefixer": "^10.4.11",
"eslint": "8.23.1",
"eslint-config-next": "12.3.0",
"postcss": "^8.4.16",
"tailwind-scrollbar": "^2.0.1",
"tailwindcss": "^3.1.8"
}
}
this is the next.config.js code:
/** #type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
}
const colors = require('tailwindcss/colors')
module.exports = {
images: {
domains: ['localhost', 'images.unsplash.com', 'googleusercontent.com','lh3.googleusercontent.com',
'firebasestorage.googleapis.com', 'googleapis.com','cloudflare-ipfs.com']
},
mode: 'jit',
theme: {
extend: {
colors: {
sky: colors.sky,
cyan: colors.cyan,
},
backgroundColor: ['active'],
},
},
variants: {},
plugins: [],
}

parceljs with bundle-text css import is not working

I am using Parcel to create bundles for my React Typescript application along with Shadow.
Below are my configurations,
///index.tsx file
import customCSS from "bundle-text:./assets/antd.scss"
const appContainer = document
.getElementById(config.containerId)
?.attachShadow({ mode: "open" }) as ShadowRoot
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
appContainer
)
let style = document.createElement("style")
style.textContent = customCSS
appContainer.appendChild(style)
And below is app.tsx file
import React, { Suspense } from "react"
import { BrowserRouter, Route, Routes } from "react-router-dom"
import "./app.scss"
import NotFound from "./pages/404"
import HomePage from "./pages/Home"
import Layout from "./pages/Layout"
const Application: React.FC<any> = () => {
return (
<Suspense fallback={<div>Loading...</div>}>
<BrowserRouter basename="/">
<Routes>
<Route path="*" element={<NotFound />} />
<Route element={<Layout />}>
<Route index element={<HomePage />} />
</Route>
</Routes>
</BrowserRouter>
</Suspense>
)
}
below is assets/antd.scss file
#import "npm:antd/dist/antd.min.css";
I have added declaration.d.ts file for declaring bundle-text:.
declare module "bundle-text:*" {
const value: string
export default value
}
ISSUE:
Now issue is that bundle-text is working fine but normal css import is not working. If I comment the bundle-text, then regular CSS import is working fine.
EXPECTED:
Both bundle-text and regular CSS import should work properly.
Below is my package.json dependencies,
"dependencies": {
"antd": "^4.18.8",
"history": "^5.2.0",
"i18next": "^21.6.11",
"parcel": "2.3.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-i18next": "^11.15.4",
"react-router-dom": "^6.2.1",
"typescript": "4.5.5"
},
"devDependencies": {
"#csstools/normalize.css": "^12.0.0",
"#parcel/transformer-inline-string": "2.3.2",
"#parcel/transformer-sass": "^2.3.2",
"#trivago/prettier-plugin-sort-imports": "^3.2.0",
"#types/react": "^17.0.39",
"#types/react-dom": "^17.0.11",
"#typescript-eslint/eslint-plugin": "^5.12.0",
"#typescript-eslint/parser": "^5.12.0",
"autoprefixer": "^10.4.2",
"eslint": "^8.9.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "^27.5.1",
"node-sass": "^7.0.1",
"parcel": "^2.3.2",
"postcss": "^8.4.6",
"postcss-modules": "^4.3.0",
"prettier": "^2.5.1",
"process": "^0.11.10",
"sass": "^1.49.8",
"typescript": "^4.5.5"
},
Is it something which I am missing here?
Update:
I have updated added my code to the sandbox environment -
parcel-shadowDOM-react-app
Unfortunately, I think this a bug in parcel - I created a simplified reproduction here and filed this github issue.
As a workaround that you could use before we fix this, I've found that if you do all your css imports through the bundle-text pipeline, parcel will keep it straight. I.e. you'll want to find places in your app where you do global css imports (e.g. import "./styles.css") with this:
import stylesString from "bundle-text:./styles.css"
let styleElement = document.createElement("style");
styleElement.textContent = stylesString ;
shadowRoot.appendChild(styleElement);
You need use sass-to-string package to transform your scss in css first

SAP UI5 : binding JSON model data to detail view

I'm trying to display the data of a JSON file into the detail view file. As I'm new to SAP UI 5, I don't understand why I get the error : "oModel.createKey is not a function" in the console.
Can anyone explain me the cause of this error please ?
I searched for some solutions and this is what I did for the moment.
Here is the main.view.xml file :
<Table id="tab1" items="{path: 'articles>/Articles'}">
<columns>
<Column width="11rem">
<Label text="ID" />
</Column>
<Column width="11rem">
<Label text="Description" />
</Column>
<Column width="11rem">
<Label text="Date début de validité" />
</Column>
<Column width="11rem">
<Label text="Date fin de validité" />
</Column>
<Column width="11rem">
<Label text="Montant" />
</Column>
</columns>
<ColumnListItem press=".onPress" type="Navigation">
<Text text="{articles>id}" />
<Text text="{articles>description}" />
<Text text="{articles>debutValidite}" />
<Text text="{articles>finValidite}" />
<Text text="{articles>prix}" />
</ColumnListItem>
</Table>
The main.controller.js file :
onInit: function () {
var oModel = new sap.ui.model.json.JSONModel();
oModel.loadData("./model/Articles.json");
this.getView().setModel(oModel,"articles");
},
onPress: function(oEvent){
var oItem = oEvent.getSource();
var oContext = oItem.getBindingContext("articles");
var sKeyId = oContext.getObject("id");
var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
oRouter.navTo("detail", {articleId: sKeyId});
The detail.view.xml file :
<f:SimpleForm id="form1">
<!--<f:content>-->
<Label text="ID"/>
<Text text="{articles>id'}"/>
<Label text="Description"/>
<Text text="{articles>description}"/>
<Label text="Date début de validité"/>
<Text text="{articles>debutValidite}"/>
<Label text="Date fin de validite"/>
<Text text="{articles>finValidite}"/>
<Label text="Montant"/>
<Text text="{articles>prix}"/>
<!--</f:content>-->
</f:SimpleForm>
The detail.controller.js file :
onInit: function () {
var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
oRouter.getRoute("detail").attachPatternMatched(this._onObjectMatched, this);
},
_onObjectMatched: function (oEvent){
var oModel = this.getView("detail").getModel("articles");
console.log(oModel);
var that= this;
var sKeyId = oEvent.getParameter("arguments").articleId;
console.log(sKeyId);
oModel.dataLoaded().then(function(){
var sPath = oModel.createKey("/Articles", {
id: sKeyId
});
that.getView().bindElement({ path: sPath});
});
},
onBack: function () {
var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
oRouter.navTo("main");
}
The Articles.json file :
{
"Articles": [{
"id": "AR00000111",
"description": "Pièce de rechange",
"debutValidite": "01.02.2020",
"finValidite": "01.05.2021",
"prix": "150"
}, {
"id": "AR00000112",
"description": "Chaise",
"debutValidite": "01.03.2020",
"finValidite": "01.05.2021",
"prix": "200"
}, {
"id": "AR00000113",
"description": "Pièce de rechange",
"debutValidite": "01.02.2020",
"finValidite": "01.09.2021",
"prix": "250"
}
]
}
And the manifest file :
"sap.ui5": {
...
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"settings": {
"bundleName": "demo.testdemo.i18n.i18n"
}
},
"articles": {
"preload": true,
"type": "sap.ui.model.json.JSONModel",
"uri": "model/Articles.json"
}
...
"routes": [{
"name": "main",
"pattern": "",
"target": ["main"]
}, {
"name": "detail",
"pattern": "detail/{articleId}",
"target": ["detail"]
}],
"targets": {
"main": {
"viewName": "main"
},
"detail": {
"viewName": "detail"
}
}
Here is the detail.view.xml :
https://i.stack.imgur.com/dvPbL.png
And the main.view.xml :
https://i.stack.imgur.com/0A5tf.png
As I understand it your model is a JSONModel. JSONModels do not have the method createKey. This method only exists in the class ODataModel.
Instead you have to work with the JSON structure. So if you have an array you have to use the indices.
const iIndex = oModel.getProperty("/Articles").findIndex(article => article.id === sKeyId);
const sPath = `/Articles/${iIndex}`;

Got "Uncaught (in promise) bad-precaching-response" when deploying next-pwa(Next.js) app in vercel

I got Uncaught (in promise) bad-precaching-response: bad-precaching-response :: [{"url":"https://myapp.vercel.app/_error","status":404}] with my next-pwa app and service worker doesn't work, when deploying my app in in vercel, though it works fine in localhost with no error.
I followed basic usage in here https://www.npmjs.com/package/next-pwa, but I use firebase-messaging-sw.js to use cloud-messaging as well as sw.js(service worker) for pwa. Also currently I don't have _error.js, which is mentioned in the above error. I thought those things might influence the error but I have no clue so far. Actually I added _error.js to my project once but it didn't make any change... Can anyone help to solve this? Thank you in advance!
next.config.js in root directory
const withPWA = require("next-pwa");
module.exports = withPWA({
pwa: {
dest: "public",
},
});
manifest.json in public directory (icons are in icons directory, which is under public dir)
{
"name": "myapp",
"short_name": "myapp",
"description": "myapp",
"start_url": "/",
"display": "standalone",
"background_color": "#fff",
"theme_color": "#fff",
"orientation": "any",
"icons": [
{
"src": "/icons/android-chrome-36x36.png",
"sizes": "36x36",
"type": "image/png"
},
,,,,,,,,,,,,,,(some more icons),,,,,,,,,,,,,,
{
"src": "/icons/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
_document.js
import Document, { Html, Head, Main, NextScript } from "next/document";
export default class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx);
return { ...initialProps };
}
render() {
return (
<Html>
<Head>
<meta
name="msapplication-square70x70logo"
content="/icons/site-tile-70x70.png"
/>
<meta
name="msapplication-square150x150logo"
content="/icons/site-tile-150x150.png"
/>
<meta
name="msapplication-wide310x150logo"
content="/icons/site-tile-310x150.png"
/>
<meta
name="msapplication-square310x310logo"
content="/icons/site-tile-310x310.png"
/>
<meta name="msapplication-TileColor" content="#000" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="#000" />
<meta name="apple-mobile-web-app-title" content="myapp" />
<link
rel="apple-touch-icon"
sizes="180x180"
href="/icons/apple-touch-icon-180x180.png"
/>
<meta name="application-name" content="myapp" />
<meta name="theme-color" content="#fff" />
<meta name="description" content="myapp" />
<link rel="icon" sizes="192x192" href="/icons/icon-192x192.png" />
<link rel="icon" href="/icons/favicon.ico" />
<link rel="manifest" href="/manifest.json" />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
package.json
{
"name": "myapp",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
},
"dependencies": {
"#material-ui/core": "^4.11.3",
"#material-ui/icons": "^4.11.2",
"#reduxjs/toolkit": "^1.5.0",
"#tailwindcss/aspect-ratio": "^0.2.0",
"#tailwindcss/forms": "^0.2.1",
"#tailwindcss/line-clamp": "^0.2.0",
"#tailwindui/react": "^0.1.1",
"autoprefixer": "^10.2.4",
"firebase": "^8.2.5",
"localforage": "^1.9.0",
"moment": "^2.29.1",
"next": "^10.1.2",
"next-pwa": "^5.1.4",
"nookies": "^2.5.2",
"nprogress": "^0.2.0",
"postcss": "^8.2.4",
"react": "17.0.1",
"react-dates": "^21.8.0",
"react-dom": "17.0.1",
"react-flip-move": "^3.0.4",
"react-redux": "^7.2.2",
"tailwindcss": "^2.0.2",
"terser-webpack-plugin": "^5.1.1"
}
}
This issue was solved by updating next-pwa 5.2.0, released today, 7th Apr, 2021.
My problem is solved after update next-pwa from 5.4.1 to 5.5.4
Change next-pwa to version "5.0.6" and it will work. It seems to create an issue with the newer versions

React, Bootstrap Nav

I'm new in React world, and stucked on beginning.
Trying to make Nav menu with react-bootstrap.Everything works fine until Nav.Item is changed.
onSelect() should change activeKey, and consequently change style on clicked Nav.Item.
index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import 'bootstrap/dist/css/bootstrap.min.css';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
App.tsx:
import NavMenu from "./components/NavMenu";
const navItems: any = [
{id: 0, name: "Home", link:"home"},
{id: 1, name: "First", link:"first"},
{id: 2, name: "Second", link:"second"}
]
const App = () => {
return (
<>
<NavMenu navItems={navItems}/>
</>
);
}
export default App;
NavMenu/idnex.tsx:
import {useState} from "react";
import {Nav} from "react-bootstrap";
const NavMenu = (props: any) => {
const {navItems} = props;
const [activeNav, setActiveNav] = useState('first')
const handleClick = (eventKey: any) => setActiveNav(eventKey);
console.log(activeNav)
return (
<div>
<Nav
defaultActiveKey="home"
className="flex-column"
activeKey={activeNav}
variant="pills"
navbar={true}
onSelect={handleClick}
>
{ navItems.map((item: any) => {
const {id, link, name} = item;
return (
<Nav.Item key={id}>
<Nav.Link href={link}
eventKey={link}>
{name}
</Nav.Link>
</Nav.Item>
);
})}
</Nav>
</div>
);
}
export default NavMenu;
package.json:
{
"name": "nav-test-case",
"version": "0.1.0",
"private": true,
"dependencies": {
"#testing-library/jest-dom": "^5.11.4",
"#testing-library/react": "^11.1.0",
"#testing-library/user-event": "^12.1.10",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-scripts": "4.0.1",
"react-bootstrap": "1.4.0",
"web-vitals": "^0.2.4",
"bootstrap": "4.5.3",
"typescript": "^4.1.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
Change is visible for one moment, and then it just rollback to default setted Nav.Item.
So it's not selected clicked Nav.Item, than the one set by default.
In Console I see change of variable from log
console.log(activeNav)
but whole page refreshes and log is reseted as well
moment before refresh
Please if someone can point me in the right direction to find out what I'm doing wrong
As far as I see it you want to have links working inside the app - but what you did is simply the way you can go to implement links to external pages.
The way to go is to use react-router-dom.
Add react-router-dom with your package manager.
Wrap your application with the BrowserRouter and define the possible Routes of your page in the Switch that defines all possible pages of your app and the according components.
<StrictMode>
<BrowserRouter>
<Switch>
<Route exact path="/" component={App} />
<Route exact path="/home" component={App} />
<Route exact path="/first" component={App} />
<Route exact path="/second" component={App} />
</Switch>
</BrowserRouter>
</StrictMode>,
Use the Link component from react-router-dom and declare your nav links as those:
<Nav.Item key={id}>
<Nav.Link as={Link} to={link} eventKey={link}>
{name}
</Nav.Link>
</Nav.Item>
That should be it.
You can see it working here: https://codesandbox.io/s/competent-cherry-8hnu9

Resources