Announcing an Open-Source Scouting App

MisCar 1574 is happy to announce

Scouting

logo

Our brand new open-source website/progressive web app, available here!

Here’s a brief overview of the app:

Decentralization

Our scouting app is a template. It is tailored to you and your team, while being a complete application with multiple features detailed below.

Ease of Setup

Scouting is easy to implement, even with minimal knowledge in web development. After you download the repository, and have Python installed, you should be up and running in minutes! Simply running the setup.py script will create your very own instance.

Once an instance is created, changing its criteria is easy, as explained in the README.

Note: the automated setup.py script does, admittedly, seem a little sketchy. This is because not everything is available in the Firebase CLI and a selenium-driven browser needs to be opened. You may wish to read the setup.py script. If you prefer, an alternative manual setup process is also provided in the README.

Minimizing Error

Web-based scouting might be unreliable, e.g., due to possible network connectivity issues. Several features address this concern:

  • The user’s query is auto-saved to the local storage of the website/pwa during its entry. Therefore, if the query closes or the device suddenly restarts, the query isn’t gone!

  • Before making the query “Submit” button available for the user, the app verifies that all criteria were filled, and notifies the user of any unfilled criteria.

  • In case of absolute emergency, a “Copy” button is available which copies the user’s query to their device’s clipboard (from which it can be forwarded via email, text message, etc) instead of using Cloud Firestore to store the queries.

Scouter Enjoyment

Scouters do miss out on the ‘action’ happening in the pits and the excitement of being a member of the drive team. However, we wish to make the scouting experience as enjoyable as it can be. A Snake minigame was added to the app, together with a leaderboard - so waiting through field delays can be fun!

We’re currently working on adding options to download the data deployed to Firestore as well as see which teams were scouted in each match, and if there were any which weren’t. Also, more games coming soon.

Additional features are detailed on the GitHub page. A live instance is also available for you to play around with here.

20 Likes

Awesome app and great code quality! I’d maybe suggest moving the setup script to JS too, just so there will only be dependency on JS tools and not on another language, and using react-router for routing although it isn’t a necessity.

1 Like

Thanks for the suggestion! I will definitely check it out.
Also, we’re using react-router-dom for routing. Did you suggest something else? It doesn’t seem like a link to me

You’re right, I skimmed that when reading the code, my bad

Hello , when l create a web app , there are some errors.

<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="/__/firebase/8.9.0/firebase-app.js"></script>

<!-- TODO: Add SDKs for Firebase products that you want to use
     https://firebase.google.com/docs/web/setup#available-libraries -->

<!-- Initialize Firebase -->
<script src="/__/firebase/init.js"></script>

It happens when l added the FireSDK

1 Like

When l run the setup.py , l have run into some errors

Installing python setup dependencies: requests selenium chromedriver-py
ERROR: Exception:
Traceback (most recent call last):
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\cli\base_command.py", line 180, in _main
    status = self.run(options, args)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\cli\req_command.py", line 205, in wrapper
    return func(self, options, args)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\commands\install.py", line 318, in run
    requirement_set = resolver.resolve(
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\resolution\resolvelib\resolver.py", line 127, in resolve
    result = self._result = resolver.resolve(
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\resolvelib\resolvers.py", line 473, in resolve
    state = resolution.resolve(requirements, max_rounds=max_rounds)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\resolvelib\resolvers.py", line 341, in resolve
    name, crit = self._merge_into_criterion(r, parent=None)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\resolvelib\resolvers.py", line 172, in _merge_into_criterion
    if not criterion.candidates:
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\resolvelib\structs.py", line 139, in __bool__
    return bool(self._sequence)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\resolution\resolvelib\found_candidates.py", line 143, in __bool__
    return any(self)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\resolution\resolvelib\found_candidates.py", line 129, in <genexpr>
    return (c for c in iterator if id(c) not in self._incompatible_ids)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\resolution\resolvelib\found_candidates.py", line 30, in _iter_built
    for version, func in infos:
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\resolution\resolvelib\factory.py", line 269, in iter_index_candidate_infos
    result = self._finder.find_best_candidate(
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\index\package_finder.py", line 879, in find_best_candidate
    candidates = self.find_all_candidates(project_name)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\index\package_finder.py", line 824, in find_all_candidates
    page_candidates = list(page_candidates_it)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\index\sources.py", line 134, in page_candidates
    yield from self._candidates_from_page(self._link)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\index\package_finder.py", line 783, in process_project_url
    html_page = self._link_collector.fetch_page(project_url)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\index\collector.py", line 512, in fetch_page
    return _get_html_page(location, session=self.session)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\index\collector.py", line 422, in _get_html_page
    resp = _get_html_response(url, session=session)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\index\collector.py", line 120, in _get_html_response
    resp = session.get(
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\requests\sessions.py", line 555, in get
    return self.request('GET', url, **kwargs)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\network\session.py", line 449, in request
    return super().request(method, url, *args, **kwargs)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\requests\sessions.py", line 542, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\requests\sessions.py", line 655, in send
    r = adapter.send(request, **kwargs)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\cachecontrol\adapter.py", line 53, in send
    resp = super(CacheControlAdapter, self).send(request, **kw)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\requests\adapters.py", line 439, in send
    resp = conn.urlopen(
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\urllib3\connectionpool.py", line 696, in urlopen
    self._prepare_proxy(conn)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\urllib3\connectionpool.py", line 964, in _prepare_proxy
    conn.connect()
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\urllib3\connection.py", line 359, in connect
    conn = self._connect_tls_proxy(hostname, conn)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\urllib3\connection.py", line 500, in _connect_tls_proxy
    return ssl_wrap_socket(
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\urllib3\util\ssl_.py", line 432, in ssl_wrap_socket
    ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\urllib3\util\ssl_.py", line 474, in _ssl_wrap_socket_impl
    return ssl_context.wrap_socket(sock)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 500, in wrap_socket
    return self.sslsocket_class._create(
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 997, in _create
    raise ValueError("check_hostname requires server_hostname")
ValueError: check_hostname requires server_hostname
WARNING: You are using pip version 21.1.3; however, version 21.2.3 is available.
You should consider upgrading via the 'C:\Users\James Assange\AppData\Local\Programs\Python\Python39\python.exe -m pip install --upgrade pip' command.
ERROR: Exception:
Traceback (most recent call last):
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\cli\base_command.py", line 180, in _main
    status = self.run(options, args)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\cli\req_command.py", line 205, in wrapper
    return func(self, options, args)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\commands\install.py", line 318, in run
    requirement_set = resolver.resolve(
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\resolution\resolvelib\resolver.py", line 127, in resolve
    result = self._result = resolver.resolve(
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\resolvelib\resolvers.py", line 473, in resolve
    state = resolution.resolve(requirements, max_rounds=max_rounds)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\resolvelib\resolvers.py", line 341, in resolve
    name, crit = self._merge_into_criterion(r, parent=None)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\resolvelib\resolvers.py", line 172, in _merge_into_criterion
    if not criterion.candidates:
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\resolvelib\structs.py", line 139, in __bool__
    return bool(self._sequence)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\resolution\resolvelib\found_candidates.py", line 143, in __bool__
    return any(self)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\resolution\resolvelib\found_candidates.py", line 129, in <genexpr>
    return (c for c in iterator if id(c) not in self._incompatible_ids)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\resolution\resolvelib\found_candidates.py", line 30, in _iter_built
    for version, func in infos:
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\resolution\resolvelib\factory.py", line 269, in iter_index_candidate_infos
    result = self._finder.find_best_candidate(
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\index\package_finder.py", line 879, in find_best_candidate
    candidates = self.find_all_candidates(project_name)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\index\package_finder.py", line 824, in find_all_candidates
    page_candidates = list(page_candidates_it)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\index\sources.py", line 134, in page_candidates
    yield from self._candidates_from_page(self._link)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\index\package_finder.py", line 783, in process_project_url
    html_page = self._link_collector.fetch_page(project_url)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\index\collector.py", line 512, in fetch_page
    return _get_html_page(location, session=self.session)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\index\collector.py", line 422, in _get_html_page
    resp = _get_html_response(url, session=session)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\index\collector.py", line 120, in _get_html_response
    resp = session.get(
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\requests\sessions.py", line 555, in get
    return self.request('GET', url, **kwargs)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\network\session.py", line 449, in request
    return super().request(method, url, *args, **kwargs)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\requests\sessions.py", line 542, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\requests\sessions.py", line 655, in send
    r = adapter.send(request, **kwargs)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\cachecontrol\adapter.py", line 53, in send
    resp = super(CacheControlAdapter, self).send(request, **kw)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\requests\adapters.py", line 439, in send
    resp = conn.urlopen(
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\urllib3\connectionpool.py", line 696, in urlopen
    self._prepare_proxy(conn)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\urllib3\connectionpool.py", line 964, in _prepare_proxy
    conn.connect()
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\urllib3\connection.py", line 359, in connect
    conn = self._connect_tls_proxy(hostname, conn)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\urllib3\connection.py", line 500, in _connect_tls_proxy
    return ssl_wrap_socket(
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\urllib3\util\ssl_.py", line 432, in ssl_wrap_socket
    ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\urllib3\util\ssl_.py", line 474, in _ssl_wrap_socket_impl
    return ssl_context.wrap_socket(sock)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 500, in wrap_socket
    return self.sslsocket_class._create(
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 997, in _create
    raise ValueError("check_hostname requires server_hostname")
ValueError: check_hostname requires server_hostname
WARNING: You are using pip version 21.1.3; however, version 21.2.3 is available.
You should consider upgrading via the 'C:\Users\James Assange\AppData\Local\Programs\Python\Python39\python.exe -m pip install --upgrade pip' command.
ERROR: Exception:
Traceback (most recent call last):
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\cli\base_command.py", line 180, in _main
    status = self.run(options, args)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\cli\req_command.py", line 205, in wrapper
    return func(self, options, args)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\commands\install.py", line 318, in run
    requirement_set = resolver.resolve(
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\resolution\resolvelib\resolver.py", line 127, in resolve
    result = self._result = resolver.resolve(
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\resolvelib\resolvers.py", line 473, in resolve
    state = resolution.resolve(requirements, max_rounds=max_rounds)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\resolvelib\resolvers.py", line 341, in resolve
    name, crit = self._merge_into_criterion(r, parent=None)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\resolvelib\resolvers.py", line 172, in _merge_into_criterion
    if not criterion.candidates:
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\resolvelib\structs.py", line 139, in __bool__
    return bool(self._sequence)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\resolution\resolvelib\found_candidates.py", line 143, in __bool__
    return any(self)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\resolution\resolvelib\found_candidates.py", line 129, in <genexpr>
    return (c for c in iterator if id(c) not in self._incompatible_ids)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\resolution\resolvelib\found_candidates.py", line 30, in _iter_built
    for version, func in infos:
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\resolution\resolvelib\factory.py", line 269, in iter_index_candidate_infos
    result = self._finder.find_best_candidate(
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\index\package_finder.py", line 879, in find_best_candidate
    candidates = self.find_all_candidates(project_name)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\index\package_finder.py", line 824, in find_all_candidates
    page_candidates = list(page_candidates_it)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\index\sources.py", line 134, in page_candidates
    yield from self._candidates_from_page(self._link)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\index\package_finder.py", line 783, in process_project_url
    html_page = self._link_collector.fetch_page(project_url)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\index\collector.py", line 512, in fetch_page
    return _get_html_page(location, session=self.session)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\index\collector.py", line 422, in _get_html_page
    resp = _get_html_response(url, session=session)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\index\collector.py", line 120, in _get_html_response
    resp = session.get(
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\requests\sessions.py", line 555, in get
    return self.request('GET', url, **kwargs)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_internal\network\session.py", line 449, in request
    return super().request(method, url, *args, **kwargs)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\requests\sessions.py", line 542, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\requests\sessions.py", line 655, in send
    r = adapter.send(request, **kwargs)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\cachecontrol\adapter.py", line 53, in send
    resp = super(CacheControlAdapter, self).send(request, **kw)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\requests\adapters.py", line 439, in send
    resp = conn.urlopen(
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\urllib3\connectionpool.py", line 696, in urlopen
    self._prepare_proxy(conn)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\urllib3\connectionpool.py", line 964, in _prepare_proxy
    conn.connect()
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\urllib3\connection.py", line 359, in connect
    conn = self._connect_tls_proxy(hostname, conn)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\urllib3\connection.py", line 500, in _connect_tls_proxy
    return ssl_wrap_socket(
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\urllib3\util\ssl_.py", line 432, in ssl_wrap_socket
    ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\site-packages\pip\_vendor\urllib3\util\ssl_.py", line 474, in _ssl_wrap_socket_impl
    return ssl_context.wrap_socket(sock)
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 500, in wrap_socket
    return self.sslsocket_class._create(
  File "C:\Users\James Assange\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 997, in _create
    raise ValueError("check_hostname requires server_hostname")
ValueError: check_hostname requires server_hostname
WARNING: You are using pip version 21.1.3; however, version 21.2.3 is available.
You should consider upgrading via the 'C:\Users\James Assange\AppData\Local\Programs\Python\Python39\python.exe -m pip install --upgrade pip' command.

Maybe python - Why requests raise this exception "check_hostname requires server_hostname"? - Stack Overflow can help you?

Something like this: pip install urllib3==1.25.11

PS, we’re working on a remake of the application and we’ll try to make the setup process even easier

Thanks , l have successfully run install the packages . But l have met anther error when running the setup.py

Waiting for authentication...
(node:7016) UnhandledPromiseRejectionWarning: FirebaseError: Failed to make request to https://firebase-public.firebaseio.com/cli.json
    at Client.doRequest (G:\FRC\Scounting app\1574\Scouting\node_modules\firebase-tools\lib\apiv2.js:211:19)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at async Client.request (G:\FRC\Scounting app\1574\Scouting\node_modules\firebase-tools\lib\apiv2.js:96:20)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:7016) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:7016) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Unfortunately, I am puzzled by this issue. I’ll try my best to check it later. As I’ve mentioned, an updated version will be released soon :upside_down_face:

Hope to here your good news soon !

MisCar 1574 is happy to announce version 2 of our redesigned open-source PWA Scouting app, available here!

Scouting is designed to make software scouting super-duper easy for teams without requiring a programming investment, while featuring the latest and greatest features.

Major new features of Scouting include:

  • Offline support: match completions from The Blue Alliance and copy/save/open scout backups are now available and make a great offline experience.
  • The admin panel shows your scouts at a glance and lets you modify the scouting form’s schema, i.e. your parameters.
  • A Google Sheets document which updates from Firestore is added.

A full feature list is available in the link above.

If you are interested in using Scouting for the 2022 season, please let us know in the following two-question form.

Note: If you have issues getting started, or want a feature to be added, or generally you just want to talk to us, our programming subteam will be glad to assist at programming@miscar1574.org and/or via GitHub (or Chief Delphi).

Documenting the setup process is in the works so please don’t hesitate to ask for help.

Shoutout to @lior_sagy for his contributions! New contributors are always welcome.

8 Likes

Is there any detailed methods to install the app? It seems that the Installation guide on the Github Page is too simple and l don’t know how to create an app based on firebase.

1 Like

This is incredible. Thank you for making it and making it available. We have never done any of this, but are interested. Do you need a paid firebase account for hosting?

2 Likes

This is a phenomenal addition, and a perfect example of designing for the user. Minigames kill boredom and the leaderboard promotes communication between team members. It’d be cool to see year-specific minigames, for example Angry Birds or a 2D tank shooter for Infinite Recharge. Although, might not want to get too carried away… :stuck_out_tongue:

2 Likes

We are trying to detail the setup process as much as we can on GitHub!

I think we will drop an update in the following days after going over it.

Thanks! It’s totally free. In fact, we aren’t planning on upgrading to the paid firebase plan, even for the season.

1 Like

I’m glad you like it! I’ll see if anyone I know is interested in developing a RAPID REACT minigame :sweat_smile:
In any case, it’s open source so if someone is willing to make it happen we will gladly accept PRs!

3 Likes

Hello,
So I tried to create an app, but may have messed it up a bit. I tried using my school email. That was a mistake as we are a Google School and tech has turned off Developer apps for the teachers. During the run, I received the window to link my Google account. The CLI set up an account with my school email, but then the initialization failed.

Enter your team's number (e.g. 1574): 6762
Already logged in as ***@SchoolEmail.org
× Creating Google Cloud Platform project

Error: Failed to create project. See firebase-debug.log for more info.
node:child_process:826
    err = new Error(msg);

I am assuming the error involves our domain restrictions. I worried that our team number may be locked into a Firebase account that I cannot log into.

So, I am wondering if anyone has any advice about how to proceed.

Is there an npm command to log out from my school email (I cannot even log into firebase)?
Do you think I did lock the team number to a ghost account?

Thank you again for your this excellent app.

Edit: So, no need to panic if this sort of thing happens to you. The initial build is just on localhost. It does not seem tied to anything. I just ran the following…

$ npm install -g firebase-tools
$ firebase logout

… and I could log in with the team email.

However, I am still getting the same error. I will keep poking around.

Edit 2:
I made a lot more progress. In order to fix the error above, I needed to log into firebase through the web console. I think the next step I need to figure out is setting up TBA. The build and deploy are failing with this error…

./src/app/services/the-blue-alliance.service.ts:2:0-48 - Error: Module not found: Error: Can't resolve 'environments/secrets.json' in 'C:\...\2022Scouting\Scouting\src\app\services'

Error: src/app/services/the-blue-alliance.service.ts:4:21 - error TS2307: Cannot find module 'environments/secrets.json' or its corresponding type declarations.

4 import Secrets from "environments/secrets.json"

I also have this problem, have you fixed it?

Yes actually. I went to TBA, logged in (you may need your mentor to do that), and generated a read-only api key).

Then, I created the missing file

environments/secrets.json

In it, I only put the following text.

{
    "TBAKey": "<key without <> symbols>"
  }	

After that, the project builds and deploys. I am getting a warning.

Warning: initial exceeded maximum budget. Budget 500.00 kB was not met by 648.75 kB with a total of 1.12 MB.

But I can log into the web portal and access the admin panel.
I can also visit the URL.
I can even play Simon.

However, I have not figured out how to add users yet.
When I try to log in as a user (in the app URL window), I get the following error.

Could not log in because of a FirebaseError: Firebase: Error (auth/configuration-not-found).

But this is looking excellent thus far.

Edit: I fixed this too.
I needed to enable Google as a sign-in method in the firebase console.

Now, I am having an issue where it says I need to select a stage to enter data, but the dropdown is empty and I cannot type.

1 Like