Error: Firebase is not configured. Ensure that you have configured 'google-services.json' correctly - expo

After running expo install expo-firebase-core expo-firebase-analytics and downloading both google-services.json and GoogleService-Info.plist from firebase console and placing them on the root of my project.
When i call Analytics.logEvent, expo go gives an error.
Possible Unhandled Promise Rejection (id: 0):
Error: Firebase is not configured. Ensure that you have configured 'google-services.json' correctly.
this is my TopLevelComponent.js:
import React from 'react'
import * as Analytics from 'expo-firebase-analytics';
import { createRootNavigator } from './router'
const RootNavigator = createRootNavigator()
const TopLevelComponent = props => {
const { screenProps } = props;
const { checkLogin } = screenProps;
const getActiveRouteName = navigationState => {
if (!navigationState) {
return null
}
const route = navigationState.routes[navigationState.index]
// Parse the nested navigators
if (route.routes) return getActiveRouteName(route)
return route.routeName
}
return (
<RootNavigator
onNavigationStateChange={async (prevState, currentState) => {
const currentScreen = getActiveRouteName(currentState)
const prevScreen = getActiveRouteName(prevState)
if (prevScreen !== currentScreen) {
checkLogin()
Analytics.logEvent('event')
}
}}
screenProps={props.screenProps}
/>
);
}
export default TopLevelComponent
Am i missing any other config?
Is there any other way to configure firebase-analytics besides this files?
I'm using expo-44.0.6 and expo-firebase-analytics-6.0.1

I had the same error.
This is how I fixed it:
Go to app.js and add
"googleServicesFile": "./GoogleService-Info.plist"
under the "iOS" section.
example:
"expo": {
"name": "",
"slug": "",
"version": "",
"orientation": "",
"icon": "",
"splash": {
"image": "",
"resizeMode": "",
"backgroundColor": ""
},
"updates": {
"fallbackToCacheTimeout":
},
"assetBundlePatterns": [
"**/*"
],
"ios": {
"supportsTablet":,
"bundleIdentifier": "",
"googleServicesFile": "./GoogleService-Info.plist"
},
Similar for Android:
"android": {
"googleServicesFile": "./google-services.json",
"adaptiveIcon": {
"foregroundImage": "",
"backgroundColor": ""
}
Add this for under the "web" section:
"web": {
"config": {
"firebase": {
"apiKey": "",
"authDomain": "",
"projectId": "",
"storageBucket": "",
"messagingSenderId": "",
"appId": "",
"measurementId": "G-**********"
}
},
"favicon": "./assets/favicon.png"
}
Then in the app:
import * as Analytics from 'expo-firebase-analytics';
const pageView = async (routeName, params) => { await Analytics.logEvent(routeName, params); };

I had same mistake. In my case i was using the Expo Bare Workflow with the SDK 45.
I only add these line in my android/build.gradle
dependencies {
classpath("com.android.tools.build:gradle:4.1.0")
classpath 'com.google.gms:google-services:4.3.10' /* Add this line */
}
And in the android/app/build.gradle on the top file
apply plugin: "com.android.application"
apply plugin: 'com.google.gms.google-services' /* Add this line */
Clean the project and run: production npx react-native run-android
That´s works for me :)

I was experiencing a similar issue connecting to analytics on Firebase. I had all the configurations mentioned above for web and ios. I wanted to set up analytics for my expo app and only use the expo-firebase-analytics library. I was testing the connection from an ios simulator.
My issue was simply resolved by adding a second app to my Firebase for the ios platform. The GoogleService-Info.plist file was auto-generated in Firebase and available to download and be placed in my project.
Initially, I only added an app to my Firebase for the web platform so I was unable to establish a connection between the ios simulator and the analytics on Firebase.

Related

jest-haste-map: Haste module naming collision (AWS, RN)

I have a React-native project with AWS Amplify.
In the root directory, there is an amplify folder.
Inside this amplify folder, there is a backend folder, and a #current-cloud-backend folder.
These two are basically identical.
When I try to start my project with npm run start I receive this error:
The following files share their name; please adjust your hasteImpl:
* <rootDir>/amplify-backup/backend/function/cxLoyaltyMainAppVerifyAuthChallengeResponse/src/package.json
* <rootDir>/amplify/#current-cloud-backend/function/cxLoyaltyMainAppVerifyAuthChallengeResponse/src/package.json
And it is complaining that inside these two folders, each lambda function has it's own package.json, in which they are named identical to their counterpart folder.
What I have done so far
I have found many people mentioning to put modulePathIgnorePatterns: ['<rootDir>/build'] inside of my root package.json under jest. Some also say to put it inside of jest.config.js which I cannot find anywhere.
I have also tried creating a root rn-cli.config.js and added
module.exports = {
resolver: {
blacklistRE: blacklist( [
/node_modules\/.*\/node_modules\/react-native\/.*/,
] )
},
};
which also does not work.
I am really running out of ideas here, anyone have any ideas? Thank you
I am using the Expo CLI and was having the same problem.
The solution that worked for me:
metro.config.js at the root directory. (instead of rn-cli.config.js)
const blacklist = require('metro-config/src/defaults/blacklist');
module.exports = {
resolver: {
blacklistRE: blacklist([/#current-cloud-backend\/.*/]),
},
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: false,
},
}),
},
};
UPDATE 2022! Just change the folder of the previous answer. It´s no longer defaults/blacklist, but defaults/exclusionList. So the solution:
I am using the Expo CLI and was having the same problem.
The solution that worked for me:
metro.config.js at the root directory. (instead of rn-cli.config.js)
const blacklist = require('metro-config/src/defaults/exclusionList');
module.exports = {
resolver: {
blacklistRE: blacklist([/#current-cloud-backend\/.*/]),
},
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: false,
},
}),
},
};
Adding the below snippet in the metro.config.js file worked for me
I am using:
react-native-cli: 2.0.1
react-native: 0.63.4
amplify: 5.3.0
const exclusionList = require('metro- config/src/defaults/exclusionList');
module.exports = {
resolver: {
blacklistRE: exclusionList([/#current-cloud-backend\/.*/]),
},
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: false,
},
}),
},
};
Also, you will need to install metro-config as a dependency by running npm i -D metro-config
In my case I have a project managed with Expo and a rule to resolve files of type cjs. I only had to include the line:
defaultConfig.resolve.blacklistRE = blacklist([/#current-cloud-backend/.*/]);
Final result:
const { getDefaultConfig } = require("#expo/metro-config");
const blacklist = require('metro-config/src/defaults/exclusionList');
const defaultConfig = getDefaultConfig(__dirname);
defaultConfig.resolve.assetExts.push("cjs");
defaultConfig.resolve.blacklistRE = blacklist([/#current-cloud-backend\/.*/]);
module.exports = defaultConfig;

Use aws-sdk in alexa skill

I am trying to develop an Alexa skill, that fetches information from a DynamoDB database. In order to use that I have to import the aws-sdk.
But for some reason when I import it, my skill stops working. The skill does not even open. My code is hosted from the Alexa Developer Console.
Here's what happens:
In the testing panel, when I input 'Open Cricket Update' (the app name), Alexa's response is, 'There was a problem with the requested skill's response'.
This happens only when I import the aws-sdk.
What am I doing wrong?
index.js
const Alexa = require('ask-sdk-core');
const AWS = require('aws-sdk');
AWS.config.update({region:'us-east-1'});
const table = 'CricketData';
const docClient = new AWS.DynamoDB.DocumentClient();
const LaunchRequestHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'LaunchRequest';
},
handle(handlerInput) {
const speakOutput = 'Hello! Welcome to cricket update.';
return handlerInput.responseBuilder
.speak(speakOutput)
.reprompt(speakOutput)
.getResponse();
}
};
package.json
{
"name": "hello-world",
"version": "1.1.0",
"description": "alexa utility for quickly building skills",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Amazon Alexa",
"license": "ISC",
"dependencies": {
"ask-sdk-core": "^2.6.0",
"ask-sdk-model": "^1.18.0",
"aws-sdk": "^2.326.0"
}
}
You are missing the exports.handler block at the end of your index.js that "builds" the skill composed from your handlers, e.g.
exports.handler = Alexa.SkillBuilders.custom()
.addRequestHandlers(LaunchRequestHandler)
.lambda();
A more complete example can be found here

How can I deploy an Electron app served by a local Django server?

I'm creating an electron app, which upon start spawns a local Django server child process (to serve as backend processing). In my development environment, the electron app runs properly when I run
npm start
Although, when trying to deploy my application with
electron-packager .
The executable does not start the Django server. When I view the contents of the resources/app directory, created by the electron packager, I see the virtualenv and all the Django dependencies are present. Why doesn't my packaged application start the local server as my development environment does?
My package.json:
{
"name": "AppName",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"start": "electron .",
"dist": "build"
},
"author": "AuthorName",
"license": "CC0-1.0",
"devDependencies": {
"electron-packager": "^14.0.1"
},
"dependencies": {
"electron": "^5.0.6"
}
}
My main.js:
// Run local Django server
var ChildProcess = require('child_process');
var DjangoServer = ChildProcess.spawn('python', ['run_server.py']);
const {app, BrowserWindow} = require('electron')
const path = require('path')
let mainWindow
function createWindow () {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
// Load local host served by Django
mainWindow.loadFile('https://localhost:8000')
mainWindow.setMenuBarVisibility(false)
mainWindow.on('closed', function () {
mainWindow = null
})
}
app.on('ready', createWindow)
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
app.on('activate', function () {
if (mainWindow === null) createWindow()
})
// Kill local Django server
app.on('before-quit', function() {
DjangoServer.kill('SIGINT')
})

How to access Vuejs methods to test with Jest?

I have the following file: deposit-form.js.
With the following code:
new Vue({
el: '#app',
data: {
title: 'title',
depositForm: {
chosenMethod: 'online',
payMethods: [
{ text: 'Already paid via Venmo', value: 'venmo' },
{ text: 'Pay online', value: 'online' },
{ text: 'In-person payment', value: 'person' }
],
},
},
methods: {
submitDeposit: function() {
$.ajax({
url: 'http://localhost:8000/api/v1/deposit/',
type:'post',
data: $('#deposit-form').serialize(),
success: function() {
$('#content').fadeOut('slow', function() {
// Animation complete.
$('#msg-success').addClass('d-block');
});
},
error: function(e) {
console.log(e.responseText);
},
});
},
showFileName: function(event) {
var fileData = event.target.files[0];
var fileName = fileData.name;
$('#file-name').text('selected file: ' + fileName);
},
},
});
I'm having problems on how to setup Jest, how to import the VueJs functions inside 'methods' to make the tests with Jest.
How should be my code on the deposit-form.test.js ?
The first thing you need to do is export Vue app instance.
// deposit-form.js
import Vue from 'vue/dist/vue.common';
export default new Vue({
el: '#app',
data: {...},
...
});
Now you can use this code in your spec file. But now you need to have #app element before running tests. This can be done using the jest setup file. I will explain why it's needed. When you import your main file (deposit-form.js) into a test, an instance of Vue is created in your main file with new. Vue is trying to mount the application into #app element. But this element is not in your DOM. That is why you need to add this element just before running the tests.
In this file you also can import jQuery globally to use it in your tests without import separately.
// jest-env.js
import $ from 'jquery';
global.$ = $;
global.jQuery = $;
const mainAppElement = document.createElement('div');
mainAppElement.id = 'app';
document.body.appendChild(mainAppElement);
Jest setup file must be specified in the jest configuration section in package.json.
// package.json
{
...,
"dependencies": {
"jquery": "^3.3.1",
"vue": "^2.6.7"
},
"devDependencies": {
"#babel/core": "^7.0.0",
"#babel/plugin-transform-modules-commonjs": "^7.2.0",
"#babel/preset-env": "^7.3.4",
"#vue/test-utils": "^1.0.0-beta.29",
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "^24.1.0",
"babel-loader": "^8.0.5",
"babel-preset-vue": "^2.0.2",
"jest": "^24.1.0",
"vue-jest": "^3.0.3",
"vue-template-compiler": "^2.6.7",
"webpack": "^4.29.5",
"webpack-cli": "^3.2.3"
},
"scripts": {
"test": "./node_modules/.bin/jest --passWithNoTests",
"dev": "webpack --mode development --module-bind js=babel-loader",
"build": "webpack --mode production --module-bind js=babel-loader"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"vue"
],
"transform": {
"^.+\\.js$": "<rootDir>/node_modules/babel-jest",
".*\\.(vue)$": "<rootDir>/node_modules/vue-jest"
},
"setupFiles": [
"<rootDir>/jest-env.js"
]
}
}
Also, you probably need to configure Babel to use the features of ES6 in your projects and tests. This is not necessary if you follow the commonjs-style in your code. Basic .babelrc file contains next code:
// .babelrc
{
"presets": [
[
"#babel/preset-env",
{
"useBuiltIns": "entry",
"targets": {
"browsers": [
"last 2 versions"
]
}
}
],
"vue",
],
"plugins": [
"#babel/plugin-transform-modules-commonjs",
]
}
Now you can write your tests.
// deposit-form.test.js
import App from './deposit-form';
describe('Vue test sample.', () => {
afterEach(() => {
const mainElement = document.getElementById('app');
if (mainElement) {
mainElement.innerHTML = '';
}
});
it('Should mount to DOM.', () => {
// Next line is bad practice =)
expect(App._isMounted).toBeTruthy();
// You have access to your methods
App.submitDeposit();
});
});
My recommendation is to learn Vue Test Utils Guides and start to divide your code into components. With the current approach, you lose all the power of components and the ability to test vue-applications.
I updated my answer a bit. As I understood from the comment to the answer, you connect the libraries on the page as separate files. Here is my mistake. I didn't ask if the build system is being used. Code in my examples is written in the ECMA-2015 standard. But, unfortunately, browsers do not fully support it. You need an transpiler that converts our files into a format that is understandable for browsers. It sounds hard. But it's not a problem. I updated the contents of the file package.json in response. Now it only remains to create an input file for the assembly and run the assembly itself.
The input file is simple.
// index.js
import './deposit-form';
The build is started with the following commands from terminal.
# for development mode
$ yarn run dev
# or
$ npm run dev
# for production mode
$ yarn run build
# or
$ npm run build
The output file will be placed in the directory ./dist/. Now instead of separate files you need to connect only one. It contains all the necessary for the library and your code.
I used webpack to build. More information about it can be found in the documentation. Good example you can find in this article.

Exporting webpack config as a function fails

I'am trying to handle development and production eviroment variables in my webpack configuration (see https://webpack.js.org/guides/production/), but it fails with
WebpackOptionsValidationError: Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration should be an object.
package.json
{
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "./node_modules/.bin/webpack",
"start": "npm run build && node server.js"
},
"devDependencies": {
//...
"webpack": "^4.20.2",
"webpack-cli": "^3.1.2",
"webpack-dev-middleware": "^3.4.0",
"webpack-hot-middleware": "^2.24.2"
}
}
webpack.config.js
const path = require('path'),
webpack = require('webpack'),
HtmlWebpackPlugin = require('html-webpack-plugin');
let config = {
entry: {
app: [
'./src/app/App.tsx', 'webpack-hot-middleware/client'
],
vendor: ['react', 'react-dom']
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'js/[name].bundle.js'
},
// ...
}
This export is working as expected without errors or warnings
module.exports = config; // everything is fine
But this fails
module.exports = function(env, argv) { // this errors
return config;
};
There is a similiar, but unanswered question here: webpack base config as a function doesn't work
It's a very mysterious behaviour, appreciate if anyone could help!
Well,it is working. I didn't notice that the error takes place on a total different spot of my code.
I was doing a tutorial about HMR with webpack and express. An it's this lines of code in the express setup which causes the trouble:
server.js
const webpackConfig = require('./webpack.config');
const compiler = webpack(webpackConfig);
//...
app.use(
require('webpack-dev-middleware')(compiler, {
noInfo: true,
publicPath: webpackConfig.output.publicPath
})
);
The webpackConfig is only getting a function without being called and so it's not returning an object. So adding parenthesis is all it took to make it work.
const webpackConfig = require('./webpack.config')();
//..
The documentation is a bit quirky. You properly forgot the set the env variable from package.json
For instance "start": "webpack --env.prod --", in package.json will pass {prod: true} as the env variable.
Hope this helps.
More info here: https://webpack.js.org/api/cli/#environment-options