In my React Native 0.68.2 "expo": "^45.0.0" app i'm trying to use react-native-firebase and i have done everything except react-native-link as it's not supported in the latest version of React Native. When I run my project, it shows error from the node module of react-native-firebase. I'm guessing it's happening for some version conflict. Here is the long error :
Error: You attempted to use a firebase module that's not installed on
your Android project by calling firebase.app().
Ensure you have:
imported the 'io.invertase.firebase.app.ReactNativeFirebaseAppPackage'
module in your 'MainApplication.java' file.
Added the 'new ReactNativeFirebaseAppPackage()' line inside of the RN
'getPackages()' method list.
See http://invertase.link/android for full setup instructions.
Here's my app build/gradle file dependencies:
classpath('com.android.tools.build:gradle:7.0.4')
classpath('com.facebook.react:react-native-gradle-plugin')
classpath('de.undercouch:gradle-download-task:4.1.2')
classpath 'com.google.gms:google-services:4.3.13'
And my android/app/build/gradle :
apply plugin: "com.android.application"
apply plugin: 'com.google.gms.google-services'
implementation "com.facebook.react:react-native:+" // From node_modules
implementation project(path: ":#react-native-firebase_messaging")
implementation project(path: ":#react-native-firebase_app")
And setting.gradle :
include ':#react-native-firebase_messaging'
project(':#react-native-firebase_messaging').projectDir = new File(rootProject.projectDir, './../node_modules/#react-native-firebase/messaging/android')
include ':#react-native-firebase_app'
project(':#react-native-firebase_app').projectDir = new File(rootProject.projectDir, './../node_modules/#react-native-firebase/app/android')
And MainApplication :
import io.invertase.firebase.messaging.ReactNativeFirebaseMessagingPackage;
packages.add(new ReactNativeFirebaseMessagingPackage());
App.js :
import messaging from '#react-native-firebase/messaging';
messaging().setBackgroundMessageHandler(async remoteMessage => {
console.log("Message handled in the background!", remoteMessage);
})
const unsub = messaging().onMessage(async remoteMessage=>{
Alert.alert('A new FCM msg arrived', JSON.stringify(remoteMessage))
console.log(remoteMessage);
return unsub;
})
app.json :
"plugins": [
"#react-native-firebase/app",
"#react-native-firebase/crashlytics",
[
"expo-build-properties",
{
"ios": {
"useFrameworks": "static"
}
}
]
],
Related
My Main goal is to create an Electron App (Windows) that locally stores data in an SQLite Database. And because of type safety I choose to use the Prisma framework instead of other SQLite Frameworks.
I took this Electron Sample Project and now try to include Prisma. Depending on what I try different problems do arrise.
1. PrismaClient is unable to be run in the Browser
I executed npx prisma generate and then try to execute this function via a button:
import { PrismaClient } from '#prisma/client';
onSqlTestAction(): void {
const prisma = new PrismaClient();
const newTestObject = prisma.testTable.create(
{
data: {
value: "TestValue"
}
}
);
}
When executing this in Electron I get this:
core.js:6456 ERROR Error: PrismaClient is unable to be run in the browser.
In case this error is unexpected for you, please report it in https://github.com/prisma/prisma/issues
at new PrismaClient (index-browser.js:93)
at HomeComponent.onSqlTestAction (home.component.ts:19)
at HomeComponent_Template_button_click_7_listener (template.html:7)
at executeListenerWithErrorHandling (core.js:15281)
at wrapListenerIn_markDirtyAndPreventDefault (core.js:15319)
at HTMLButtonElement.<anonymous> (platform-browser.js:568)
at ZoneDelegate.invokeTask (zone.js:406)
at Object.onInvokeTask (core.js:28666)
at ZoneDelegate.invokeTask (zone.js:405)
at Zone.runTask (zone.js:178)
It somehow seems logical that Prisma cannot run in a browser. But I actually build a native app - with Electron that embeds a Browser. It seems to be a loophole.
2. BREAKING CHANGE: webpack < 5 used to include polyfills
So i found this Question: How to use Prisma with Electron
Seemed to be exactly what I looked for. But the error message is different (Debian binaries were not found).
The solution provided is to generate the prisma artifacts into the src folder instead of node_modules - and this leads to 19 polyfills errors. One for example:
./src/database/generated/index.js:20:11-26 - Error: Module not found: Error: Can't resolve 'path' in '[PATH_TO_MY_PROJECT]\src\database\generated'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "path": require.resolve("path-browserify") }'
- install 'path-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "path": false }
And this repeats with 18 other modules. Since the error message to begin with was different I also doubt that this is the way to go.
I finally figured this out. What I needed to understand was, that all Electron apps consist of 2 parts: The Frontend Webapp (running in embedded Chromium) and a Node backend server. Those 2 parts are called IPC Main and IPC Renderer and they can communicate with each other. And since Prisma can only run on the main process which is the backend I had to send my SQL actions to the Electron backend and execute them there.
My minimal example
In the frontend (I use Angular)
// This refers to the node_modules folder of the Electron Backend, the folder where the main.ts file is located.
// I just use this import so that I can use the prisma generated classes for type safety.
import { TestTable } from '../../../app/node_modules/.prisma/client';
// Button action
onSqlTestAction(): void {
this.electronService.ipcRenderer.invoke("prisma-channel", 'Test input').then((value) => {
const testObject: TestTable = JSON.parse(value);
console.log(testObject);
});
The sample project I used already had this service to provide the IPC Renderer:
#Injectable({
providedIn: 'root'
})
export class ElectronService {
ipcRenderer: typeof ipcRenderer;
webFrame: typeof webFrame;
remote: typeof remote;
childProcess: typeof childProcess;
fs: typeof fs;
get isElectron(): boolean {
return !!(window && window.process && window.process.type);
}
constructor() {
// Conditional imports
if (this.isElectron) {
this.ipcRenderer = window.require('electron').ipcRenderer;
this.webFrame = window.require('electron').webFrame;
this.childProcess = window.require('child_process');
this.fs = window.require('fs');
// If you want to use a NodeJS 3rd party deps in Renderer process (like #electron/remote),
// it must be declared in dependencies of both package.json (in root and app folders)
// If you want to use remote object in renderer process, please set enableRemoteModule to true in main.ts
this.remote = window.require('#electron/remote');
}
}
And then in the Electron backend I first added "#prisma/client": "^3.0.1" to the package.json (for the Electron backend not the frontend). Then I added to the main.ts this function to handle the requests from the renderer:
// main.ts
ipcMain.handle("prisma-channel", async (event, args) => {
const prisma = new PrismaClient();
await prisma.testTable.create(
{
data: {
value: args
}
}
);
const readValue = await prisma.testTable.findMany();
return JSON.stringify(readValue);
})
This way of simply adding the IPC Main handler in the main.ts file of course is a big code smell but usefull as minimal example. I think I will move on with the achitecture concept presented in this article.
I am using the AWS Amplify Storage module to store and retrieve user files using the JavaScript API. When I serve or build with Parcel, the following error message is printed to the console:
TypeError: S3 is not a constructor
at AWSS3Provider._createS3 (AWSS3Provider.ts:501)
at AWSS3Provider.<anonymous> (AWSS3Provider.ts:130)
at step (AWSS3Provider.ts:19)
at Object.next (AWSS3Provider.ts:19)
at fulfilled (AWSS3Provider.ts:19)
The error occurs with Parcel v1.12.4 and AWS Amplify v2.2.4.
Minimal steps to reproduce
An appropriately configured Cognito identity pool and S3 bucket per the AWS Amplify Storage documentation are needed.
The following files should all be in the same directory.
A package.json with dependencies.
{
"main": "index.js",
"dependencies": {
"aws-amplify": "^2.2.4",
"lodash": "^4.17.15"
}
}
An aws-exports.js that specifies the identity pool and S3 bucket:
export const awsconfig = {
Auth: {
identityPoolId: "xx-xxxx-x:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
region: "xx-xxxx-x"
},
Storage: {
AWSS3: {
bucket: "a-bucket-name",
region: "xx-xxxx-x"
}
}
};
An index.html:
<!DOCTYPE html>
<html lang="en">
<body>
<main></main>
<script src="./index.js"></script>
</body>
</html>
An index.js:
import Amplify, { Storage } from "aws-amplify";
import { awsconfig } from "./aws-exports";
Amplify.configure(awsconfig);
// not required, but helps to confirm everything else worked
window.LOG_LEVEL = "DEBUG";
Storage.get("test.txt")
.then(result => console.log(result))
.catch(err => console.log(err));
Run the following
npm install
parcel index.html
then view the page and error message in the console.
Note that replacing the call to Storage.get() with Storage.configure() does not produce an error.
I have tried bundling the same with a default webpack configuration, and I do not observe the error. This makes me suspect that I may need to override some parcel configuration.
I encountered this when deploying Lambdas using #aws-cdk/aws-lambda-nodejs.
I worked around this by using the aws-sdk available in the Lambda runtime environment instead of bundling my own copy in each Lambda's assets. It should equally apply to other assets that end up running in Lambda.
npm install --save-dev parcel-plugin-externals
Add to package.json:
"externals": [
"aws-sdk"
]
Instantiate S3 client using
import * as AWS from 'aws-sdk';
const s3 = new AWS.S3();
instead of
import * as S3 from 'aws-sdk/clients/s3';
const s3 = new S3();
References:
https://github.com/aws/aws-cdk/issues/7685
i want to build an application and use firebase for notification done a lot of search over google but did not find any good guide and solution , everything i tried ended into some errors . i tried ionic docs but they are all messy after the ionic v4 they shows everything about v4 i have my app almost finished up just this thing remains .
i will appreciate any help .
Any idea how to proceed? I'm most probably not configuring Firebase properly. I have placed google-services.json in the root directory, no problems there. but after that its all out of my understanding
AN ERROR OCCURRED WHILE RUNNING ionic cordova plugin add phonegap-plugin-push --variable SENDER_ID-150482406038 --SAVE EXIT CODE 1
Got this Working . Thanks everyone for help!
refrences used-
https://ionicframework.com/docs/v3/native/push/
https://github.com/phonegap/phonegap-plugin-push
works for
ionic 3.20.1
cordova 8.1.2
steps i followed
Removed my android platform using ionic cordova platform
removeandroid then i created it agin ionic cordova platform add
android. just to avoid any errors which my be there with my old
android version.
Got the google-services.json and placed it in the
rootDirectoryOfApp\platforms\android\app
then i run $ ionic cordova plugin add phonegap-plugin-push $ npm
install --save #ionic-native/push#4
Edit config.xml look for <platform name="android"> under that i
wrote <resource-file src="google-services.json"
target="app/google-services.json" />
Edit package.json look for "phonegap-plugin-push" and edit it
something like this
"phonegap-plugin-push": {
"ANDROID_SUPPORT_V13_VERSION": "27.+", // already there
"FCM_VERSION": "11.6.2", // already there
"SENDER_ID": "numeric key obtain from firebase console" // added
},
Open app.module.ts and import import { Push } from
'#ionic-native/push'; add Push under providers there ...
providers: [
StatusBar,
SplashScreen,
Push, ....
Then in a provider
i imported import { Push, PushObject, PushOptions } from '#ionic-native/push';
then in costructor i added private push: Push,
and in the class of that provider i wrote a function like below
pushSetup(){
// to check if we have permission
this.push.hasPermission()
.then((res: any) => {
if (res.isEnabled) {
console.log('We have permission to send push notifications');
} else {
console.log('We do not have permission to send push notifications');
}
});
// Create a channel (Android O and above). You'll need to provide the id, description and importance properties.
this.push.createChannel({
id: "testchannel1",
description: "My first test channel",
// The importance property goes from 1 = Lowest, 2 = Low, 3 = Normal, 4 = High and 5 = Highest.
importance: 3
}).then(() => console.log('Channel created'));
// Delete a channel (Android O and above)
this.push.deleteChannel('testchannel1').then(() => console.log('Channel deleted'));
// Return a list of currently configured channels
this.push.listChannels().then((channels) => console.log('List of channels', channels))
// to initialize push notifications
const options: PushOptions = {
android: {
senderID:"150482406038",
},
ios: {
alert: 'true',
badge: true,
sound: 'false'
},
};
const pushObject: PushObject = this.push.init(options);
pushObject.on('notification').subscribe((notification: any) => console.log('Received a notification', notification));
pushObject.on('registration').subscribe((registration: any) => console.log('Device registered', registration));
pushObject.on('error').subscribe(error => console.error('Error with Push plugin', error));
}
Now imported that provider where I want to use that , and called
that function from there . but call it only after
this.platform.ready().then(() => { or when a successful login.
I have shared this because i found it little difficult and got confusing guides over web
Please comment if you found it wrong or not working in your case.
I have been using this tutorial: https://medium.com/#felipepucinelli/how-to-add-push-notifications-in-your-cordova-application-using-firebase-69fac067e821 and Android push notifications worked out of the box. Good luck!
^ you might wanna try the cordova-plugin-firebase plugin as Chrillewoodz has mentioned
I am trying to get network status in ionic2, Ionic-native docs example is not working: My code is:
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { Network } from '#ionic-native/network';
#Component( {
selector: 'page-network',
templateUrl: 'network.html'
})
export class NetworkPage {
Status: any = '';
ConnectionType:any = '';
constructor(private network: Network) {
let disconnectSubscription = this.network.onDisconnect().subscribe(() => {
this.Status = 'Disconnected';
console.log('network was disconnected ');
});
disconnectSubscription.unsubscribe();
let connectSubscription = this.network.onConnect().subscribe(() => {
console.log('network connected!');
this.Status = 'Connected';
setTimeout(() => {
if (this.network.type === 'wifi') {
console.log('we got a wifi connection, woohoo!');
}
}, 3000);
});
connectSubscription.unsubscribe();
}
}
i have using ionic2. error not come but still it not working for me. Need to check if network status enable or disable.
Make sure that you #ionic-native/core is installed, and in app.module.ts add Network to the providers in #NgModule decorator, finally you must inject or call the created service in somewhere usually in app.component.ts
Upadate
Remove the unsubscribe method on the listeners
disconnectSubscription.unsubscribe();
connectSubscription.unsubscribe();
I found out that you first subscribe to the network event then unsubscribe
Steps to make it work
Create ionic2 project
run the commands
ionic plugin add cordova-plugin-network-information
npm install --save #ionic-native/network
Add Network service in the providers array in the app.module.ts
In app.component.ts use this code.
Add the required platform lets choose Android
ionic platform add android
Then run the code
ionic run android
Finally try to enable/disable wifi and watch the console
I encounter the same issue this was how i solved it.
Make sure your
"#ionic-native/core": "~4.18.0",
and
"#ionic-native/network": "^4.18.0",
are the same version
by checking "#ionic-native/core" version on package.json in your project and installing
"#ionic-native/network" with the same version of "#ionic-native/core" e.g if "#ionic-native/core" version is "4.18.0" then install "#ionic-native/network" of 4.18.0 version
npm install #ionic-native/network#4.18.0
It should work like that.
I'm trying to login with Google but it throws me this error:
code: "auth/operation-not-supported-in-this-environment"
message: "This operation is not supported in the environment this application is running on. "location.protocol" must be http, https or chrome-extension and web storage must be enabled."
This is the code:
const provider = new firebase.auth.GoogleAuthProvider();
provider.addScope('profile');
provider.addScope('email');
firebase.auth().signInWithPopup(provider)
.then((result) => {
console.log(result);
})
.catch((error) => {
console.log(error);
})
Aditional Information:
"firebase": "^3.7.1"
"react-native": "^0.42.0"
platform: Android
any ideas?
thanks in advance!
First I used react-native-google-signin to Sign In with Google. Follow these steps to configure it.
Make sure you correctly sign your APK (debug or release).
In app/build.gradle exclude com.google.android.gms from the dependencies that use it like so:
compile(project(":react-native-google-signin")){
exclude group: "com.google.android.gms" // very important
}
Then link you Google token with Firebase:
const provider = firebase.auth.GoogleAuthProvider;
const credential = provider.credential(token);
firebase.auth().signInWithCredential(credential)
.then((data) => {
console.log('SUCCESS', data);
})
.catch((error) => {
console.log('ERROR', error);
});
I'm using firebase 3.7.1
This is how my dependencies look in app/build.gradle
dependencies {
compile project(':react-native-facebook-login')
compile (project(':react-native-fcm')){
exclude group: "com.google.firebase"
}
compile project(':react-native-vector-icons')
compile fileTree(dir: "libs", include: ["*.jar"])
compile "com.android.support:appcompat-v7:23.0.1"
compile "com.facebook.react:react-native:+"
compile(project(":react-native-google-signin")){
exclude group: "com.google.android.gms" // very important
}
compile ('com.google.firebase:firebase-core:10.0.1') {
force = true;
}
compile ('com.google.firebase:firebase-messaging:10.0.1') {
force = true;
}
compile ('com.google.android.gms:play-services-auth:10.0.1') {
force = true;
}
}
Firebase Documentation
"Headful" auth methods such as signInWithPopup(), signInWithRedirect(), linkWithPopup(), and linkWithRedirect() do not work in React Native (or Cordova, for that matter). You can still sign in or link with a federated provider by using signInWithCredential() with an OAuth token from your provider of choice.
The general issue is not about changing the code with the solution, is more than we you use npm link the solution will be broke again, as the npm link will be re-adding the new line causing the error again.
npm link will search with regex, the current line is
compile(project(":react-native-google-signin")){ so we need to change it to the format compile project ("package") and split to the next like the bracket char.
In the following way:
compile project(":react-native-google-signin")
{
exclude group: "com.google.android.gms" // very important
}
so when you run npm link, it will detect the dependency and won't be duplicated but also the if block code will be persisted.
I am replying late but it will be helpful for others, if you are using firebase with google sign then you must exclude some libraries and those your app gradle like that
compile(project(":react-native-google-signin")){
exclude group: "com.google.android.gms" // very important
}
compile ('com.google.android.gms:play-services-auth:10.2.6'){
force = true;
}
compile ("com.google.android.gms:play-services-base:+") { // the plus allows you to use the latest version
force = true;
}
compile (project(path: ':react-native-fbsdk')){
exclude group: "com.google.android.gms"
}
compile(project(":react-native-firebase")){
exclude group: "com.google.android.gms"
}
This is discussion about that issue for more detail answer
I find all other answers to be either incorrect or deprecated.
react-native-firebase which is the officially recommended collection of packages that brings React Native support for all Firebase services on both Android and iOS apps.
Be sure to follow Firebase Authentication setup instructions: https://rnfirebase.io/auth/usage
Setup Firebase Authentication with google-signin: https://github.com/react-native-google-signin/google-signin