Categories
discuss

Attempted import error: ‘app’ is not exported from ‘firebase/app’ (imported as ‘firebase’)

Encountered a very weird issue. When trying to import firebase, I got the following error:

./node_modules/firebaseui/dist/esm.js
Attempted import error: 'app' is not exported from 'firebase/app' (imported as 'firebase').

The structure of my project is: A parent folder containing a react client folder. I installed firebase in the parent folder, initialize a firebase app in the firebaseConfig file in the parent folder, and then import it into the react client folder.

I later tried installing firebase in the react client folder and import firebase in it. Weirdly, after I installed firebase in the client folder, doing “npm ls firebase” in the client folder returns empty, even though firebase is indeed in the node modules and package.json in the client folder. I am wondering what caused the problem.

firebaseConfig.js in the parent folder

import firebase from 'firebase/app';
import 'firebase/firestore';
import 'firebase/auth';

const firebaseConfig = {
    ......
};

firebase.initializeApp(firebaseConfig);

export default firebase;

Answer

Unfortunately, you’ve upgraded your “firebase” dependency to 8.0.0 but the “firebaseui” dependency doesn’t support it yet. You will have to temporarily downgrade firebase to version 7.24.0 until firebaseui supports the breaking changes in 8.0.0.

Categories
discuss

ReferenceError: document is not defined in Next.js while working with React Aria overlays

I’m learning Next.js for web development and I came across commerce, a boilerplate for e-commerce websites written in Next.js. As I was browsing through the code I found the Sidebar component which uses React Aria for creating overlays.

I wanted to use this part in my own project, so wrote a Overlay component that also uses the OverlayContainer component.

import { useRef } from 'react';

import {
    useOverlay,
    useModal,
    OverlayContainer
} from '@react-aria/overlays';

const Overlay = ({ className, children, open = false, onClose }) => {
    const ref = useRef(null);

    const { modalProps } = useModal();

    let { overlayProps } = useOverlay({ onClose: onClose, open: open, isDismissable: true }, ref);
    return (
        <OverlayContainer>
            <div
                {...overlayProps}
                {...modalProps}
                ref={ref}
            >
                {children}
            </div>
        </OverlayContainer>

    );
};

export default Overlay;

This component gets loaded in my Layout component, just as in the commerce project. However, when I try to load up the index page, it gives me the following error:

Server Error
ReferenceError: document is not defined

This error happened while generating the page. Any console logs will be displayed in the terminal window.
Source
pages/_document.tsx (90:33) @ Function.getInitialProps

  88 |     }
  89 | 
> 90 |     const { html, head } = await ctx.renderPage({ enhanceApp })
     |                                 ^
  91 |     const styles = [...flush()]
  92 |     return { html, head, styles }
  93 |   }

When I remove the OverlayContainer component, it loads all fine. I tried updating my dependencies, comparing more code to the Github repo, but nothing found so far.

What’s the problem here? And how could I fix it? I’m using Next 10 with React 17.0.1.

Answer

A workaround that you can do is isBrowser which is fairly common for NextJS apps.

const isBrowser = typeof window !== "undefined";

Use it to conditionally render your OverlayContainer.

import { useRef } from "react";

import { useOverlay, useModal, OverlayContainer } from "@react-aria/overlays";

/**
 * Utility to detect if you're on the server, or in the browser.
 */
const isBrowser = typeof window !== "undefined";

const Overlay = ({ className, children, open = false, onClose }) => {
  const ref = useRef(null);

  const { modalProps } = useModal();

  let { overlayProps } = useOverlay(
    { onClose: onClose, open: open, isDismissable: true },
    ref
  );
  return isBrowser ? (
    <OverlayContainer>
      <div {...overlayProps} {...modalProps} ref={ref}>
        {children}
      </div>
    </OverlayContainer>
  ) : null;
};

export default Overlay;

Categories
discuss

Android : Validate half-width Japanese character

This question might have been asked several times but I didn’t find a proper answer so I am posting this question. What I want to do is validate the Japanese text entered in the edit text field to allow only half-width Japanese characters. I only want to check the validation once user enters the text and taps on some action button.

Answer

Okay so I came across many solutions and this one worked for me. Basically, I have a Japanese half-width validation regex and compared it to my string.

val halfWidthRegex = "^[ァ-ン゙゚]+\s?[ァ-ン゙゚]+$"

if(myText?.matches(halfWidthRegex.toRegex()))
  // Valid halfwidth text
else // Invalid halfwidth text.
Categories
discuss

Sharing data on WhatsApp not working on android 11

After upgrading my project on API 30, I checked WhatsApp data sharing via intent not working on android 11 device May b due to Package visibility in Android 11

 val imgBitmapPath = MediaStore.Images.Media.insertImage(mContext.contentResolver, bitmap, "eVitalRx_Greetings_" + Calendar.getInstance().getTime(), null)
    val imgUri = Uri.parse(imgBitmapPath)
    val whatsappIntent = Intent(Intent.ACTION_SEND)
    if (appInstalledOrNot(mContext, "com.whatsapp")) {
        whatsappIntent.setPackage("com.whatsapp")
    } else {
        whatsappIntent.setPackage("com.whatsapp.w4b")
    }
    whatsappIntent.putExtra(Intent.EXTRA_TEXT, msg)
    whatsappIntent.putExtra(Intent.EXTRA_STREAM, imgUri)
    whatsappIntent.type = "image/jpeg"
    whatsappIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
    try {
        mContext.startActivity(whatsappIntent)
    } catch (ex: ActivityNotFoundException) {
        Toast.makeText(mContext, "Whatsapp not installed", Toast.LENGTH_LONG).show()
    }

It displaying the message "Whatsapp not installed" in android 11 device.

Does anyone have a solution for this?

Answer

Finally, I got an answer by spending time with the original document and some other links.

if you want any kind of interaction with other apps you must add the package’s name into the manifest file.

 <queries>
       
        <package android:name="com.whatsapp" />
        <package android:name="com.whatsapp.w4b" />
       
 </queries>
Categories
discuss

Programmatically create multiple types of pages in Gatsby.js

I’m building a website with GatsbyJS. I have markdown files in two different folders: /content/collections and /content/posts and I want Gatsby to create a page for each markdown file, with the respective template (collection.js and post.js).

So I wrote this in my gatsby-node.js file:

const path = require('path');
const { createFilePath } = require('gatsby-source-filesystem');
exports.onCreateNode = ({ node, getNode, actions }) => {
  const { createNodeField } = actions;
  if (node.internal.type === 'MarkdownRemark') {
    const longSlug = createFilePath({ node, getNode, basePath: 'content' });
    const slug = longSlug.split('/');
    createNodeField({
      node,
      name: 'slug',
      value: `/${slug[slug.length - 2]}/`,
    });
  }
};

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions;
  const result = await graphql(`
    query {
      allFile(filter: {relativeDirectory: {eq: "collections"}}) {
        edges {
          node {
            childMarkdownRemark {
              fields {
                slug
              }
            }
          }
        }
      }
    }
  `);
  result.data.allFile.edges.forEach(({ node }) => {
    createPage({
      path: node.childMarkdownRemark.fields.slug,
      component: path.resolve('./src/templates/collection.js'),
      context: {
        slug: node.childMarkdownRemark.fields.slug,
      },
    });
  });
};

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions;
  const result = await graphql(`
    query {
      allFile(filter: {relativeDirectory: {eq: "posts"}}) {
        edges {
          node {
            childMarkdownRemark {
              fields {
                slug
              }
            }
          }
        }
      }
    }
  `);
  result.data.allFile.edges.forEach(({ node }) => {
    createPage({
      path: node.childMarkdownRemark.fields.slug,
      component: path.resolve('./src/templates/post.js'),
      context: {
        slug: node.childMarkdownRemark.fields.slug,
      },
    });
  });
};

Thinking that it would work. It does work for the second type that I put in. (in this case it creates the posts, but not the collections. If I invert the order in which I call createPages it swaps, but it never creates all of them)

This is the error that I get in the console:

warning The GraphQL query in the non-page component "/Users/matteocarpi/Documents/Web/Ledue/src/templates/collection.js" will not be run.
Exported queries are only executed for Page components. It's possible you're
trying to create pages in your gatsby-node.js and that's failing for some
reason.

If the failing component(s) is a regular component and not intended to be a page
component, you generally want to use a <StaticQuery> (https://gatsbyjs.org/docs/static-query)
instead of exporting a page query.

If you're more experienced with GraphQL, you can also export GraphQL
fragments from components and compose the fragments in the Page component
query and pass data down into the child component — https://graphql.org/learn/queries/#fragments

The two templates are very similar:

import React from 'react';

import { graphql } from 'gatsby';
import PropTypes from 'prop-types';

const Post = ({data}) => {
  return (
    <div>
      <h1>{data.postData.frontmatter.title}</h1>
    </div>
  );
};

export default Post;

export const query = graphql`
query PostData($slug: String!) {
  postData: markdownRemark(fields: {slug: {eq: $slug}}) {
    frontmatter {
      title
    }
  }
}
`;

Post.propTypes = {
  data: PropTypes.node,
};
import React from 'react';

import { graphql } from 'gatsby';
import PropTypes from 'prop-types';

const Collection = ({data}) => {
  return (
    <div>
      <h1>{data.collectionData.frontmatter.title}</h1>
    </div>
  );
};

export default Collection;

export const query = graphql`
query CollectionData($slug: String!) {
  collectionData: markdownRemark(fields: {slug: {eq: $slug}}) {
    frontmatter {
      title
    }
  }
}
`;

Collection.propTypes = {
  data: PropTypes.node,
};

I tried refactoring all of the gatsby-node.js file following this answer but I end up in the same situation.

Where am I getting it wrong?

Answer

The issue is that you’re overriding your first function declaration with the second. A bit like this:

var a = "hello"
a = "world"

Instead you should do all of your querying and call createPage for all pages you want to create in a single function, something like this:

exports.createPages = ({ graphql, actions }) => {
  const { createPage } = actions;

  const collections = graphql(`
    query {
      allFile(filter: {relativeDirectory: {eq: "collections"}}) {
        edges {
          node {
            childMarkdownRemark {
              fields {
                slug
              }
            }
          }
        }
      }
    }
  `).then(result => {
    result.data.allFile.edges.forEach(({ node }) => {
      createPage({
        path: node.childMarkdownRemark.fields.slug,
        component: path.resolve('./src/templates/collection.js'),
        context: {
          slug: node.childMarkdownRemark.fields.slug,
        },
      });
    });
  })

  const posts = graphql(`
    query {
      allFile(filter: {relativeDirectory: {eq: "posts"}}) {
        edges {
          node {
            childMarkdownRemark {
              fields {
                slug
              }
            }
          }
        }
      }
    }
  `).then(result => {
    result.data.allFile.edges.forEach(({ node }) => {
      createPage({
        path: node.childMarkdownRemark.fields.slug,
        component: path.resolve('./src/templates/post.js'),
        context: {
          slug: node.childMarkdownRemark.fields.slug,
        },
      });
    });
  })

  return Promise.all([collections, posts])
};
Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..