3

My Google Maps API Key works properly when I hardcode it to the tag like this:

<head>

  <script src="https://maps.googleapis.com/maps/api/js?key=HARD_CODED_HERE"></script>
</head>

Now, I don't want to hard code the value and I need to get it from .env files.

What I have tried and worked so far was:

in the main.dart:

  js.context['googleMapsApiKey'] = dotenv.env['GOOGLE_MAPS_API_KEY'];
  html.document.dispatchEvent(html.CustomEvent("google-maps-api-key-loaded"));

Basically creating a DOM element for capturing after in the index.html like this:

in the index.html:

 <script>
    document.addEventListener("google-maps-api-key-loaded", function (){
      var googleapis = window.GOOGLE_MAPS_API_KEY;
      var script = document.createElement('script');
      script.src = "https://maps.googleapis.com/maps/api/js?key=" + googleapis + "&callback=initMap";
      script.defer = true;
      script.async = true;
      document.head.appendChild(script);
    });
    
  </script>

The problem is that this solution works only on web because I needed to import these to main.dart:

main.dart file:

import 'dart:js' as js;
import 'dart:html' as html;

Which will not allow iOS and Android to run because these import are intended for web apps, only.

Is any body using similar approach? Or any suggestion for a solution? Preferably without using additional package.

Thanks

3 Answers 3

3

In the end, the solution that I've found was installing the package universal_html: https://pub.dev/packages/universal_html

The imports should look like this:

import 'package:universal_html/js.dart' as js;
import 'package:universal_html/html.dart' as html;

I hope this helps somenone.

Sign up to request clarification or add additional context in comments.

Comments

1

hmm so mobile needs the app key.

dart define the app key for mobile. You would need to enter it twice, once in the vscode launch and once in the task part. Then in dart check if not web and read the env key via dart define.

1 Comment

Fred Appreciate your suggestion but I am looking at other solution at the moment. Thanks
-1

I passed the Google Maps API Key using a different approach and I am using Envied Package to load API Key from .env file. Here's a step-by-step guide:

Step 1: Create Platform-Specific Configuration Files

Create two files: configure_web.dart and configure_nonweb.dart.

1.1 In configure_web.dart, add the following code:

import 'dart:html' as web;
import 'package:app/env.dart';

void configureApp() {
  final apiKey = Env.googleMapsKey;
  final element = web.document.createElement('script') as web.ScriptElement;
  element.src = 'https://maps.googleapis.com/maps/api/js?key=$apiKey&loading=async';
  element.async = true;
  web.document.head?.append(element);
}

1.2 In configure_nonweb.dart, add this no-op function for non-web platforms:

void configureApp() {
  // No-op for non-web platforms
}

Step 2: Call the Function in main.dart

In your main.dart, call the configureApp function like this:

void main() async {
  // --- other initialization code ---
  configureApp();  // Call to configure API
  // --- other initialization code ---
  runApp();
}

Step 3: Use Conditional Imports

Finally, use conditional imports to ensure the correct configuration file is used depending on the platform:

// Conditional import: Web loads `configure_web.dart`, others load `configure_nonweb.dart`
import 'package:app/configure_nonweb.dart'
    if (dart.library.html) 'package:app/configure_web.dart';

Main Function:

My main function looks like this:

import 'package:app/app_bootstrap.dart';
import 'package:flutter/material.dart';
// ignore:depend_on_referenced_packages
import 'package:flutter_web_plugins/url_strategy.dart';
// Conditional import: Web loads `configure_web.dart`, others load `configure_nonweb.dart`
import 'package:app/configure_nonweb.dart'
    if (dart.library.html) 'package:app/configure_web.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // turn off the # in the URLs on the web
  usePathUrlStrategy();
  // Inject Google Maps script on web
  configureApp();

  final appBootStrap = AppBootStrap();
  final container = await appBootStrap.createProviderContainer();
  final root = appBootStrap.createRootWidget(container: container);
  runApp(root);
}

and no need to pass anything in index.html and also don't add this:

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.