Bootstrap accordion looping through posts incorrectly

Your problem is that you’re using the_ID() to give an ID to each taxonomy term, but the_ID() doesn’t output the ID of the current term in a foreach loop, it get’s the ID of the current post.

Since you’re not resetting postdata in your custom queries this will be the ID of the last post of the previous term.

To give a unique ID to each accordion, use the term’s ID with $term->term_id:

<?php
/*
 * Loop through Categories and Display Posts within
 */
$post_type="faqs";

// Get all the taxonomies for this post type
$taxonomies = get_object_taxonomies( array( 'post_type' => $post_type ) );

foreach( $taxonomies as $taxonomy ) :
    // Gets every "category" (term) in this taxonomy to get the respective posts
    $terms = get_terms( $taxonomy );

    foreach( $terms as $term ) : 
        $args = array(
            'post_type'      => $post_type,
            'posts_per_page' => -1,  //show all posts
            'tax_query'      => array(
                array(
                    'taxonomy' => $taxonomy,
                    'field'    => 'slug',
                    'terms'    => $term->slug,
                )
            )

        );
        ?>

        <h2 style="margin-bottom: 20px;">
            <a data-toggle="collapse" data-parent="#accordion" href="#collapse-<?php echo $term->term_id; ?>" aria-expanded="true" aria-controls="collapse-<?php echo $term->term_id ?>">
                <?php echo $term->name; ?> +
            </a>
        </h2>

        <div id="collapse-<?php echo $term->term_id; ?>" class="panel-collapse collapse <?php if( $c == 1 ) echo 'in'; ?>" role="tabpanel" aria-labelledby="heading-<?php echo $term->term_id; ?>">

            <?php $localfaqs = new WP_Query( $args );?>

            <?php if ( $localfaqs->have_posts() ) : while ( $localfaqs->have_posts() ) : $localfaqs->the_post(); $c++; ?>
                <div class="row">    
                    <?php 
                    $faqs = get_field('local');

                    if ( $faqs ) : foreach ( $faqs as $p ): // variable must NOT be called $post (IMPORTANT) 
                        ?>

                        <div class="col-md-half faq-circle">
                            <div class="celeb-circle-faq">
                                <a href="<?php echo get_permalink( $p->ID ); ?>"><?php echo get_the_post_thumbnail( $p->ID ); ?></a>
                            </div>
                        </div>

                    <?php endforeach; endif; ?>

                    <div class="col-md-10 faq-link">
                        <a href="<?php the_permalink();?>">
                            <?php the_title();?>
                        </a>
                    </div>
                </div>
            <?php endwhile; endif; wp_reset_postdata(); ?>
        </div>
    <?php
    endforeach;
endforeach;

What I changed was collapse-<?php the_ID(); ?> to collapse-<?php echo $term->term_id ?> and heading-<?php the_ID(); ?> to heading-<?php echo $term->term_id; ?>.

I also added wp_reset_postdata(); after the custom query loops, so that any code coming after the loop isn’t referencing the incorrect post.