I'm having some difficulty setting up push notifications with my Firebase app. I followed this tutorial to the letter on setting up cloud messaging
I'd like mobile devices to be able to receive notifications, so I add the requestPermssions() function directly to my index.html
<!-- Firebase -->
<script src="https://www.gstatic.com/firebasejs/3.4.0/firebase.js"></script>
<script src="https://www.gstatic.com/firebasejs/3.4.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/3.4.0/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/3.4.0/firebase-database.js"></script>
<script src="https://www.gstatic.com/firebasejs/3.4.0/firebase-storage.js"></script>
...
...
<script>
var config = {
apiKey: "56sds55hhjh906rwsbghghsd",
authDomain: "app-33aef.firebaseapp.com",
databaseURL: "https://app-33aef.firebaseio.com",
storageBucket: "app-33aef.appspot.com",
messagingSenderId: "43532673275"
};
firebase.initializeApp(config)
const messaging = firebase.messaging();
messaging.requestPermission()
.then(function(){
console.log('Have Permissions!');
return messaging.getToken()
})
.then(function(token){
console.log(token);
})
.catch(function(error){
console.warn('ERROR: ' + error);
})
messaging.onMessage(function(payload){
console.log('onMessage', payload);
})
</script>
However I'm seeing the following TypeError
firebase.messaging is not a function
After scouring the web I've read that you have to use firebase-admin to use the messaging() function. I've tried that as well but then I get an `Unexpected token import' error, but that may just be my project setup...
Does anyone have a solution for this? I feel like I'm going in circles here for something very simple
Well, I feel that this was so obvious that I never would have thought about it.
Include the script tag for firebase messaging (oy vey).
<script src="https://www.gstatic.com/firebasejs/4.2.0/firebase-messaging.js"></script>
It would have been helpful to mention this in the video as many others were stumped as well
Related
I tried to use firebase auth on the app, it runs fine on android emu and able to create account and login but not on web(chrome). When I run the debug it gave an error of TypeError: Cannot read properties of undefined (reading 'app'). But if I run flutter build web --release and open the web link it returns
ReferenceError: firebase is not defined. I have been google-ing for days, still unable to fix this issue. I'm at the dead-end not sure what to do. the const firebaseConfig = {...}; in the index.html was given from firebase auth when created an webapp project.
Please help. not sure where it went wrong.
flutter doctor
[√] Flutter (Channel stable, 2.5.0, on Microsoft Windows [Version 10.0.22454.1000],locale
en-US)
[√] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[√] Chrome - develop for the web
[√] Android Studio (version 2020.3)
[√] VS Code (version 1.60.2)
[√] Connected device (2 available)
flutter --version
Flutter 2.5.0 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 4cc385b4b8 (2 weeks ago) • 2021-09-07 23:01:49 -0700
Engine • revision f0826da7ef
Tools • Dart 2.14.0
in the pupspec.yaml
name: login_test
description: A new Flutter project.
publish_to: 'none'
version: 1.0.0+1
environment:
sdk: ">=2.12.0 <3.0.0"
dependencies:
cupertino_icons: ^1.0.2
firebase_auth: ^3.1.1
firebase_core: ^1.6.0
flutter:
sdk: flutter
fluttertoast: ^8.0.8
form_field_validator: ^1.1.0
dev_dependencies:
flutter_lints: ^1.0.0
flutter_test:
sdk: flutter
flutter:
uses-material-design: true
in the web/index.html
<!DOCTYPE html>
<html>
<head>
<!--
If you are serving your web app in a path other than the root, change the
href value below to reflect the base path you are serving from.
The path provided below has to start and end with a slash "/" in order for
it to work correctly.
For more details:
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
This is a placeholder for base href that will be replaced by the value of
the `--base-href` argument provided to `flutter build`.
-->
<base href="$FLUTTER_BASE_HREF">
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="A new Flutter project.">
<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="login_test">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<title>login_test</title>
<link rel="manifest" href="manifest.json">
</head>
<body>
<!-- Firebase Configuration -->
<script type="module">
// Import the functions you need from the SDKs you need
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.0.2/firebase-app.js";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
import { auth } from "https://www.gstatic.com/firebasejs/9.0.2/firebase-auth.js"
// Your web app's Firebase configuration
const firebaseConfig = {
apiKey: "_________-_________",
authDomain: "_________-_________.firebaseapp.com",
projectId: "_________-_________",
storageBucket: "_________-_________.appspot.com",
messagingSenderId: "_________",
appId: "1:_________:web:_________"
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
</script>
<!-- This script installs service_worker.js to provide PWA functionality to
application. For more information, see:
https://developers.google.com/web/fundamentals/primers/service-workers -->
<script>
var serviceWorkerVersion = null;
var scriptLoaded = false;
function loadMainDartJs() {
if (scriptLoaded) {
return;
}
scriptLoaded = true;
var scriptTag = document.createElement('script');
scriptTag.src = 'main.dart.js';
scriptTag.type = 'application/javascript';
document.body.append(scriptTag);
}
if ('serviceWorker' in navigator) {
// Service workers are supported. Use them.
window.addEventListener('load', function () {
// Wait for registration to finish before dropping the <script> tag.
// Otherwise, the browser will load the script multiple times,
// potentially different versions.
var serviceWorkerUrl = 'flutter_service_worker.js?v=' + serviceWorkerVersion;
navigator.serviceWorker.register(serviceWorkerUrl)
.then((reg) => {
function waitForActivation(serviceWorker) {
serviceWorker.addEventListener('statechange', () => {
if (serviceWorker.state == 'activated') {
console.log('Installed new service worker.');
loadMainDartJs();
}
});
}
if (!reg.active && (reg.installing || reg.waiting)) {
// No active web worker and we have installed or are installing
// one for the first time. Simply wait for it to activate.
waitForActivation(reg.installing || reg.waiting);
} else if (!reg.active.scriptURL.endsWith(serviceWorkerVersion)) {
// When the app updates the serviceWorkerVersion changes, so we
// need to ask the service worker to update.
console.log('New service worker available.');
reg.update();
waitForActivation(reg.installing);
} else {
// Existing service worker is still good.
console.log('Loading app from service worker.');
loadMainDartJs();
}
});
// If service worker doesn't succeed in a reasonable amount of time,
// fallback to plaint <script> tag.
setTimeout(() => {
if (!scriptLoaded) {
console.warn(
'Failed to load app from service worker. Falling back to plain <script> tag.',
);
loadMainDartJs();
}
}, 4000);
});
} else {
// Service workers not supported. Just drop the <script> tag.
loadMainDartJs();
}
</script>
<script src="main.dart.js" type="application/javascript"></script>
</body>
</html>
I think that I got what's happening. The problem is to integrate Flutter compiled to web with Firebase web api.
The FlutterFire (it is the Flutter library to integrate with Firebase) was developed to integrate with the Firebase web api version 8.6.1.
On the other hand, Firebase web api is already in version 9.x, and it has different method calls on initialization. So, the solution is to use Flutter web api 8.6.1 instead of 9.x like de Flutter web api documentation.
The confusion comes from when a beginner create a new Firebase app at the console and the page gives a code to put on the flutter web index.html, but in this case the code use Firebase web api 9.x version style.
TL;DR;
The code in the Flutter web/index.html needs to be exactly like this. Put in the beginning of the body tag. Just replace your firebaseConfig object.
<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-app.js"></script>
<script>
var firebaseConfig = {
apiKey: "----",
authDomain: "----",
projectId: "----",
storageBucket: "----",
messagingSenderId: "----",
appId: "----"
};
firebase.initializeApp(firebaseConfig);
</script>
Use this libraries but replace the version to 8.6.1.
You should really follow the official docs. If you follow it from the start carefully it will take you there. You'll occasionally see web-specific stuff like this:
https://firebase.flutter.dev/docs/installation/web
https://firebase.flutter.dev/docs/firestore/overview#3-web-only-add-the-sdk
We use it in Flutter Web just fine using these instructions. Your index.html looks different from what's there in the docs. You probably followed a tutorial somewhere that is probably outdated now.
I am making a chrome extension with a custom popup that comes up after the page is loaded.
I would like to safe the submitted answers from the input-field to my firebase database, so that i cant include them in another website. It all works, but the problem is, that the answers from the extension get blocked:
Cross-Origin Read Blocking (CORB) blocked cross-origin response with MIME type text/plain. See for more details.
How can i solve this Problem?
Note: I am not a pro at this, so i'd really appreciate an easy to follow solution:)
these are my steps:
I downloaded the firebase.js and added it to my manifest.json:
"matches": ["<all_urls>"],
"js": [ "Libraries/firebase-app.js",
"Libraries/firebase-firestore.js",
"sketch.js"],
I injected the html to the webpage using the content-script:
<div id="bg-modal">
<div class="modal-content">
<button class="close">+</button>
<div class="text"></div>
<form class="antwortfeld antwortfeld1" action="">
<textarea type="text" name="antwort" placeholder="Antworten"></textarea>
<button class="Senden">Senden</button>
</form>
I added the firebase app configuration and initialized firebase in the content-script
// Your web app's Firebase configuration
var firebaseConfig = {
apiKey: "...TRZeHhLQ9gMa4V4gy9WSlQ",
authDomain: "....firebaseapp.com",
databaseURL: "https://....firebaseio.com",
projectId: "....",
storageBucket: "....appspot.com",
messagingSenderId: "...0021",
appId: "1:385077100021:.....ba5a776b4bc"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
const db = firebase.firestore();
then i added this to the content-script as well to save the inputdata to firebase:
const form1 = document.querySelector('.antwortfeld1');
// saving data
form1.addEventListener('submit', (e) => {
e.preventDefault();
db.collection('Antworten').add({
Antwort1: form1.antwort.value,
})
form1.antwort.value = ' ';
})
As I said, it's all working, but I get blocked. I guess I'll have to use a background-script to get around this? What would that look like?
Any other options?
I implemented a Login with Google API following the Firebase Authentication docs (Authenticate Using OAuth Providers with Cordova) Link. However, it shows the Project Default AUTH_DOMAIN. How do I change it to show custom URL?
<universal-links>
<host name="example.page.link" scheme="https" />
<host name="example-app.firebaseapp.com" scheme="https">
<path url="/__/auth/callback"/>
</host>
</universal-links>
Have you set your domain when adding Firebase to your app?
<script src="https://www.gstatic.com/firebasejs/5.8.2/firebase.js"></script>
<script>
// Initialize Firebase
// TODO: Replace with your project's customized code snippet
var config = {
apiKey: "<API_KEY>",
authDomain: "<PROJECT_ID>.firebaseapp.com",
databaseURL: "https://<DATABASE_NAME>.firebaseio.com",
projectId: "<PROJECT_ID>",
storageBucket: "<BUCKET>.appspot.com",
messagingSenderId: "<SENDER_ID>",
};
firebase.initializeApp(config);
</script>
Also, using your own domain is not as easy as it sounds. Check out this post for more info.
I'm trying to add firebase authentication to my google doc add on. My goal is to have a sidebar that displays data from my database after authentication. I get the most confused by other answers because I'm unsure about what goes in the html file verse what goes in the google app script file. I know I'm supposed to create a token but after I copy and paste that code from the tutorial I get lost.
Groups/Answers that were partly helpful:
https://groups.google.com/forum/#!topic/firebase-talk/-RKpHaMPTYQ
Google Authentication with Google Spread Sheet via App Script
https://sites.google.com/site/scriptsexamples/new-connectors-to-google-services/firebase/tutorials/using-secured-client-authentication-for-real-time-read-and-write-calls
app.html
<html lang="en">
<head>
<script src="https://www.gstatic.com/firebasejs/3.7.3/firebase.js"></script>
<script>
var config = {
apiKey: "",
authDomain: "",
databaseURL: "",
storageBucket: "",
messagingSenderId: ""
};
firebase.initializeApp(config);
</script>
</head>
<body>
<div id="databaseDiv"></div>
</body>
</html>
Code.gs
/**
* Creates a menu entry in the Google Docs UI when the document is opened.
* This method is only used by the regular add-on, and is never called by
* the mobile add-on version.
*
* #param {object} e The event parameter for a simple onOpen trigger. To
* determine which authorization mode (ScriptApp.AuthMode) the trigger is
* running in, inspect e.authMode.
*/
function onOpen(e) {
DocumentApp.getUi().createAddonMenu()
.addItem('Start', 'showSidebar')
.addToUi();
}
function onInstall(e) {
onOpen(e);
}
function showSidebar() {
var ui = HtmlService.createHtmlOutputFromFile('app')
.setTitle('Sow Google Docs');
DocumentApp.getUi().showSidebar(ui);
}
function makeToken(){
var firebaseUrl = "https://example.firebaseio.com/";
var secret = "EXAMPLEKEYYEKELPMAXE";
var base = FirebaseApp.getDatabaseByUrl(firebaseUrl, secret);
var token = base.createAuthToken(Session.getActiveUser().getEmail());
return token;
}
What am I missing?
Do not use any custom firebase library for apps script, use the Official Firebase Inline Javascript Libraries to achieve your objectives. If you run into problems ask your questions here (but do not be clueless), people will help.
I had used the following script to integrate google authentication
//google auth code
gapi.load('auth2', function() {//load in the auth2 api's, without it gapi.auth2 will be undefined
gapi.auth2.init(
{
client_id: '1063305095705-k68gpfhi46tbu6kv8e8tidc751hte5pb.apps.googleusercontent.com'
}
);
var GoogleAuth = gapi.auth2.getAuthInstance();//get's a GoogleAuth instance with your client-id, needs to be called after gapi.auth2.init
$scope.onLogInButtonClick=function(){//add a function to the controller so ng-click can bind to it
GoogleAuth.signIn().then(function(response){//request to sign in
console.log(response);
console.log(response.wc.wc);
console.log(response.wc.hg);
console.log(response.wc.Ph);
});
};
});
I am trying to use this in some other application and getting the following error :-
gapi.auth2.ExternallyVisibleError: gapi.auth2 has been initialized with
different options. Consider calling gapi.auth2.getAuthInstance()
instead of gapi.auth2.init().
I've also included
<script src="https://apis.google.com/js/platform.js?key=xxxxxxxxx"></script>
Everything seems to be fine, don't understand why it does not work..
Next code should help:
I have been spent two hours of solving this and because I was receiving the same error, I decided to use onLoad function with custom google sign in button.
Some points, that are probably neccessary if we do not want get profile info from users...
use onload function as in code below, when using defer async method:
https://apis.google.com/js/platform.js?onload=onLoadCallback
make your own sign in button with click event on signIn function
<a onclick="signIn();">Google Sign In</a>
Full solution is here:
<script src="https://apis.google.com/js/platform.js?onload=onLoadCallback" async defer></script>
<meta name="google-signin-client_id" content="YOUR_ID.apps.googleusercontent.com"/>
<!-- I have commented default google sign in button because it didn't allow me to make my own gapi.load -->
<!--<div class="g-signin2" data-onsuccess="ConSignIn"></div>-->
<a onclick="signIn();">Google Sign In</a>
<script>
function onLoadCallback() {
console.log('onLoadCallback');
gapi.load('auth2', function() {
gapi.auth2.init({
client_id: 'YOUR_ID.apps.googleusercontent.com',
//This two lines are important not to get profile info from your users
fetch_basic_profile: false,
scope: 'email'
});
});
}
function signIn() {
console.log('I am passing signIn')
var auth2 = gapi.auth2.getAuthInstance();
// Sign the user in, and then retrieve their ID.
auth2.signIn().then(function() {
console.log(auth2.currentUser.get().getId());
});
}
</script>